docs: def detect_type(err, install_rdf=None, xpi_package=None):
      """Determines the type of add-on being validated based on
      install.rdf, file extension, and other properties."""
  
      # The types in the install.rdf don't pair up 1:1 with the type
      # system that we're using for expectations and the like. This is
      # to help translate between the two.
      translated_types = {'2': PACKAGE_EXTENSION,
                          '4': PACKAGE_THEME,
                          '8': PACKAGE_LANGPACK,
                          '32': PACKAGE_MULTI,
                          '64': PACKAGE_DICTIONARY,
                          # New "experiment" types: see bug 1220097 and
                          # https://github.com/mozilla/addons-server/issues/3315
                          '128': PACKAGE_EXTENSION,
                          '256': PACKAGE_EXTENSION,}
  
      # If we're missing our install.rdf file, we can try to make some
      # assumptions.
      if install_rdf is None:
          types = {'xpi': PACKAGE_DICTIONARY}
  
          err.notice(('typedetection',
                      'detect_type',
                      'missing_install_rdf'),
                     'install.rdf was not found.',
                     'The type should be determined by install.rdf if present. '
                     "If it isn't, we still need to know the type.")
  
          # If we know what the file type might be, return it.
          if xpi_package.extension in types:
              return types[xpi_package.extension]
          # Otherwise, we're out of luck :(
          else:
              return None
  
      # Attempt to locate the <em:type> node in the RDF doc.
      type_uri = install_rdf.uri('type')
      type_ = install_rdf.get_object(None, type_uri)
  
      # Dictionaries are weird too, they might not have the obligatory
      # em:type. We can assume that if they have a /dictionaries/ folder,
      # they are a dictionary because even if they aren't, dictionaries
      # have an extraordinarily strict set of rules and file filters that
      # must be passed. It's so crazy secure that it's cool if we use it
      # as kind of a fallback.
  
      if any(file_ for file_ in xpi_package if
                 file_.startswith('dictionaries/')):
          if type_ != '64':
              err.error(('typedetection',
                         'dictionary_valid_type',
                         'invalid_em_type'),
                        'Invalid <em:type> value.',
                        'The package appears to be a dictionary but does not have '
                        'the correct <em:type> set in the install manifest.')
          return PACKAGE_DICTIONARY
  
      if type_ is not None:
          if type_ in translated_types:
              err.save_resource('is_multipackage', type_ == '32', pushable=True)
              # Make sure we translate back to the normalized version
              return translated_types[type_]
          else:
              err.error(('typedetection',
                         'detect_type',
                         'invalid_em_type'),
                        'Invalid <em:type> value.',
                        'The only valid values for <em:type> are 2, 4, 8, and '
                        '32. Any other values are either invalid or deprecated.',
                        'install.rdf')
              return
      else:
          err.notice(
              err_id=('typedetection',
                      'detect_type',
                      'no_em:type'),
              notice='No <em:type> element found in install.rdf',
              description="It isn't always required, but it is the most reliable "
                          'method for determining add-on type.',
              filename='install.rdf')
  
      # There's no type element, so the spec says that it's either a
      # theme or an extension. At this point, we know that it isn't
      # a dictionary, language pack, or multiple extension pack.
      extensions = {'jar': '4',
                    'xpi': '2'}
  
      # If the package's extension is listed in the [tiny] extension
      # dictionary, then just return that. We'll validate against that
      # add-on type's layout later. Better to false positive than to false
      # negative.
      if xpi_package.extension in extensions:
          # Make sure it gets translated back to the normalized version
          install_rdf_type = extensions[xpi_package.extension]
          return translated_types[install_rdf_type]