parameters: (root, predetermined_tids)
return_statement: return tids
docstring: Returns a dict of textual id -> numeric id for all nodes in root.
  
    IDs are mostly assigned sequentially, but will vary based on:
      * first_id node attribute (from first_ids_file)
      * hash of textual id (if not first_id is defined)
      * offset node attribute
      * whether the textual id matches a system id
      * whether the node generates its own ID via GetId()
  
    Args:
      predetermined_tids: Dict of textual id -> numeric id to use in return dict.
docstring_summary: Returns a dict of textual id -> numeric id for all nodes in root.
docstring_tokens: Returns a dict of textual id - > numeric id for all nodes in root .
function: def _ComputeIds(root, predetermined_tids):
    """Returns a dict of textual id -> numeric id for all nodes in root.
  
    IDs are mostly assigned sequentially, but will vary based on:
      * first_id node attribute (from first_ids_file)
      * hash of textual id (if not first_id is defined)
      * offset node attribute
      * whether the textual id matches a system id
      * whether the node generates its own ID via GetId()
  
    Args:
      predetermined_tids: Dict of textual id -> numeric id to use in return dict.
    """
    from grit.node import empty, include, misc, structure
  
    ids = {}  # Maps numeric id to textual id
    tids = {}  # Maps textual id to numeric id
    id_reasons = {}  # Maps numeric id to text id and a human-readable explanation
    group = None
    last_id = None
    predetermined_ids = {value: key
                         for key, value in predetermined_tids.items()}
  
    for item in root:
      if isinstance(item, empty.GroupingNode):
        # Note: this won't work if any GroupingNode can be contained inside
        # another.
        group = item
        last_id = None
        continue
  
      assert not item.GetTextualIds() or isinstance(item,
          (include.IncludeNode, message.MessageNode,
           misc.IdentifierNode, structure.StructureNode))
  
      # Resources that use the RES protocol don't need
      # any numerical ids generated, so we skip them altogether.
      # This is accomplished by setting the flag 'generateid' to false
      # in the GRD file.
      if item.attrs.get('generateid', 'true') == 'false':
        continue
  
      for tid in item.GetTextualIds():
        if util.SYSTEM_IDENTIFIERS.match(tid):
          # Don't emit a new ID for predefined IDs
          continue
  
        if tid in tids:
          continue
  
        if predetermined_tids and tid in predetermined_tids:
          id = predetermined_tids[tid]
          reason = "from predetermined_tids map"
  
        # Some identifier nodes can provide their own id,
        # and we use that id in the generated header in that case.
        elif hasattr(item, 'GetId') and item.GetId():
          id = long(item.GetId())
          reason = 'returned by GetId() method'
  
        elif ('offset' in item.attrs and group and
              group.attrs.get('first_id', '') != ''):
          offset_text = item.attrs['offset']
          parent_text = group.attrs['first_id']
  
          try:
            offset_id = long(offset_text)
          except ValueError:
            offset_id = tids[offset_text]
  
          try:
            parent_id = long(parent_text)
          except ValueError:
            parent_id = tids[parent_text]
  
          id = parent_id + offset_id
          reason = 'first_id %d + offset %d' % (parent_id, offset_id)
  
        # We try to allocate IDs sequentially for blocks of items that might
        # be related, for instance strings in a stringtable (as their IDs might be
        # used e.g. as IDs for some radio buttons, in which case the IDs must
        # be sequential).
        #
        # We do this by having the first item in a section store its computed ID
        # (computed from a fingerprint) in its parent object.  Subsequent children
        # of the same parent will then try to get IDs that sequentially follow
        # the currently stored ID (on the parent) and increment it.
        elif last_id is None:
          # First check if the starting ID is explicitly specified by the parent.
          if group and group.attrs.get('first_id', '') != '':
            id = long(group.attrs['first_id'])
            reason = "from parent's first_id attribute"
          else:
            # Automatically generate the ID based on the first clique from the
            # first child of the first child node of our parent (i.e. when we
            # first get to this location in the code).
  
            # According to
            # http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx
            # the safe usable range for resource IDs in Windows is from decimal
            # 101 to 0x7FFF.
  
            id = FP.UnsignedFingerPrint(tid)
            id = id % (0x7FFF - 101) + 101
            reason = 'chosen by random fingerprint -- use first_id to override'
  
          last_id = id
        else:
          id = last_id = last_id + 1
          reason = 'sequentially assigned'
  
        reason = "%s (%s)" % (tid, reason)
        # Don't fail when 'offset' is specified, as the base and the 0th
        # offset will have the same ID.
        if id in id_reasons and not 'offset' in item.attrs:
          raise exception.IdRangeOverlap('ID %d was assigned to both %s and %s.'
                                         % (id, id_reasons[id], reason))
  
        if id < 101:
          print('WARNING: Numeric resource IDs should be greater than 100 to\n'
                'avoid conflicts with system-defined resource IDs.')
  
        if tid not in predetermined_tids and id in predetermined_ids:
          raise exception.IdRangeOverlap('ID %d overlaps between %s and %s'
                                         % (id, tid, predetermined_ids[tid]))
  
        ids[id] = tid
        tids[tid] = id
        id_reasons[id] = reason
  
    return tids
function_tokens: def _ComputeIds ( root , predetermined_tids ) : from grit . node import empty , include , misc , structure ids = { } # Maps numeric id to textual id tids = { } # Maps textual id to numeric id id_reasons = { } # Maps numeric id to text id and a human-readable explanation group = None last_id = None predetermined_ids = { value : key for key , value in predetermined_tids . items ( ) } for item in root : if isinstance ( item , empty . GroupingNode ) : # Note: this won't work if any GroupingNode can be contained inside # another. group = item last_id = None continue assert not item . GetTextualIds ( ) or isinstance ( item , ( include . IncludeNode , message . MessageNode , misc . IdentifierNode , structure . StructureNode ) ) # Resources that use the RES protocol don't need # any numerical ids generated, so we skip them altogether. # This is accomplished by setting the flag 'generateid' to false # in the GRD file. if item . attrs . get ( 'generateid' , 'true' ) == 'false' : continue for tid in item . GetTextualIds ( ) : if util . SYSTEM_IDENTIFIERS . match ( tid ) : # Don't emit a new ID for predefined IDs continue if tid in tids : continue if predetermined_tids and tid in predetermined_tids : id = predetermined_tids [ tid ] reason = "from predetermined_tids map" # Some identifier nodes can provide their own id, # and we use that id in the generated header in that case. elif hasattr ( item , 'GetId' ) and item . GetId ( ) : id = long ( item . GetId ( ) ) reason = 'returned by GetId() method' elif ( 'offset' in item . attrs and group and group . attrs . get ( 'first_id' , '' ) != '' ) : offset_text = item . attrs [ 'offset' ] parent_text = group . attrs [ 'first_id' ] try : offset_id = long ( offset_text ) except ValueError : offset_id = tids [ offset_text ] try : parent_id = long ( parent_text ) except ValueError : parent_id = tids [ parent_text ] id = parent_id + offset_id reason = 'first_id %d + offset %d' % ( parent_id , offset_id ) # We try to allocate IDs sequentially for blocks of items that might # be related, for instance strings in a stringtable (as their IDs might be # used e.g. as IDs for some radio buttons, in which case the IDs must # be sequential). # # We do this by having the first item in a section store its computed ID # (computed from a fingerprint) in its parent object.  Subsequent children # of the same parent will then try to get IDs that sequentially follow # the currently stored ID (on the parent) and increment it. elif last_id is None : # First check if the starting ID is explicitly specified by the parent. if group and group . attrs . get ( 'first_id' , '' ) != '' : id = long ( group . attrs [ 'first_id' ] ) reason = "from parent's first_id attribute" else : # Automatically generate the ID based on the first clique from the # first child of the first child node of our parent (i.e. when we # first get to this location in the code). # According to # http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx # the safe usable range for resource IDs in Windows is from decimal # 101 to 0x7FFF. id = FP . UnsignedFingerPrint ( tid ) id = id % ( 0x7FFF - 101 ) + 101 reason = 'chosen by random fingerprint -- use first_id to override' last_id = id else : id = last_id = last_id + 1 reason = 'sequentially assigned' reason = "%s (%s)" % ( tid , reason ) # Don't fail when 'offset' is specified, as the base and the 0th # offset will have the same ID. if id in id_reasons and not 'offset' in item . attrs : raise exception . IdRangeOverlap ( 'ID %d was assigned to both %s and %s.' % ( id , id_reasons [ id ] , reason ) ) if id < 101 : print ( 'WARNING: Numeric resource IDs should be greater than 100 to\n' 'avoid conflicts with system-defined resource IDs.' ) if tid not in predetermined_tids and id in predetermined_ids : raise exception . IdRangeOverlap ( 'ID %d overlaps between %s and %s' % ( id , tid , predetermined_ids [ tid ] ) ) ids [ id ] = tid tids [ tid ] = id id_reasons [ id ] = reason return tids