'Render/process the form.
@param request: the S3Request
@param resource: the target S3Resource
@param record_id: the record ID
@param readonly: render the form read-only
@param message: message upon successful form submission
@param format: data format extension (for audit)
@param options: keyword options for the form
@return: a FORM instance'

def __call__(self, request=None, resource=None, record_id=None, readonly=False, message='Record    created/updated', format=None, **options):

    db = current.db
    response = current.response
    s3 = response.s3
    if (resource is None):
        resource = request.resource
        (self.prefix, self.name, self.table, self.tablename) = request.target()
    else:
        self.prefix = resource.prefix
        self.name = resource.name
        self.tablename = resource.tablename
        self.table = resource.table
    self.resource = resource
    subtables = set()
    subtable_fields = {}
    fields = []
    components = []
    for element in self.elements:
        (alias, name, field) = element.resolve(resource)
        if isinstance(alias, str):
            subtables.add(alias)
            if (field is not None):
                fields_ = subtable_fields.get(alias)
                if (fields_ is None):
                    fields_ = []
                fields_.append((name, field))
                subtable_fields[alias] = fields_
        elif isinstance(alias, S3SQLFormElement):
            components.append(alias)
        if (field is not None):
            fields.append((alias, name, field))
    self.subtables = subtables
    self.components = components
    rcomponents = resource.components
    if subtables:
        if (not request):
            from s3rest import S3Request
            r = S3Request(resource.prefix, resource.name, args=[], get_vars={})
        else:
            r = request
        customise_resource = current.deployment_settings.customise_resource
        for alias in subtables:
            if (alias not in rcomponents):
                continue
            tablename = rcomponents[alias].tablename
            customise = customise_resource(tablename)
            if customise:
                customise(r, tablename)
            renamed_fields = subtable_fields.get(alias)
            if renamed_fields:
                table = rcomponents[alias].table
                for (name, renamed_field) in renamed_fields:
                    original_field = table[name]
                    for attr in ('comment', 'default', 'readable', 'represent', 'requires', 'update', 'writable'):
                        setattr(renamed_field, attr, getattr(original_field, attr))
    if (not readonly):
        mark_required = self._config('mark_required', default=[])
        (labels, required) = s3_mark_required(self.table, mark_required)
        if required:
            s3.has_required = True
        else:
            s3.has_required = False
    else:
        labels = None
    settings = s3.crud
    if (format == 'plain'):
        formstyle = 'table3cols'
    elif readonly:
        formstyle = settings.formstyle_read
    else:
        formstyle = settings.formstyle
    record = None
    if (record_id is not None):
        query = (self.table._id == record_id)
        record = db(query).select(limitby=(0, 1)).first()
    self.record_id = record_id
    self.subrows = Storage()
    data = None
    noupdate = []
    forbidden = []
    has_permission = current.auth.s3_has_permission
    if (record is not None):
        subrows = self.subrows
        for alias in subtables:
            component = rcomponents[alias]
            if component.multiple:
                continue
            join = component.get_join()
            q = (query & join)
            row = db(q).select(component.table.ALL, limitby=(0, 1)).first()
            ctname = component.tablename
            if (not row):
                component = rcomponents[alias]
                permitted = has_permission('create', ctname)
                if (not permitted):
                    forbidden.append(alias)
                continue
            else:
                cid = row[component.table._id]
                permitted = has_permission('read', ctname, cid)
                if (not permitted):
                    forbidden.append(alias)
                    continue
                permitted = has_permission('update', ctname, cid)
                if (not permitted):
                    noupdate.append(alias)
            subrows[alias] = row
        pkey = self.table._id
        data = Storage({pkey.name: record[pkey]})
        for (alias, name, field) in fields:
            if (alias is None):
                if (name in record):
                    data[field.name] = record[name]
            elif (alias in subtables):
                if ((alias in subrows) and (subrows[alias] is not None) and (name in subrows[alias])):
                    data[field.name] = subrows[alias][name]
            elif hasattr(alias, 'extract'):
                data[field.name] = alias.extract(resource, record_id)
    else:
        self.record_id = record_id = None
        for alias in subtables:
            if (alias in rcomponents):
                component = rcomponents[alias]
            else:
                continue
            permitted = has_permission('create', component.tablename)
            if (not permitted):
                forbidden.append(alias)
    fields = [f for f in fields if (f[0] not in forbidden)]
    for (a, n, f) in fields:
        if a:
            if (a in noupdate):
                f.writable = False
            if ((labels is not None) and (f.name not in labels)):
                if f.required:
                    flabels = s3_mark_required([f], mark_required=[f])[0]
                    labels[f.name] = flabels[f.name]
                elif f.label:
                    labels[f.name] = ('%s:' % f.label)
                else:
                    labels[f.name] = ''
    if readonly:
        for (a, n, f) in fields:
            f.comment = None
    else:
        for alias in subtables:
            if (alias in rcomponents):
                component = rcomponents[alias]
                mark_required = component.get_config('mark_required', [])
                ctable = component.table
                sfields = dict(((n, (f.name, f.label)) for (a, n, f) in fields if ((a == alias) and (n in ctable))))
                slabels = s3_mark_required([ctable[n] for n in sfields], mark_required=mark_required, map_names=sfields)[0]
                if labels:
                    labels.update(slabels)
                else:
                    labels = slabels
    self.subtables = [s for s in self.subtables if (s not in forbidden)]
    formfields = [f[(-1)] for f in fields]
    buttons = self._submit_buttons(readonly)
    tablename = self.tablename
    response.form_label_separator = ''
    form = SQLFORM.factory(record=data, showid=False, labels=labels, formstyle=formstyle, table_name=tablename, upload=s3.download_url, readonly=readonly, separator='', submit_button=settings.submit_button, buttons=buttons, *formfields)
    if (settings.submit_style and (not settings.custom_submit)):
        try:
            form[0][(-1)][0][0]['_class'] = settings.submit_style
        except:
            pass
    subheadings = options.get('subheadings', None)
    if subheadings:
        self._insert_subheadings(form, tablename, formstyle, subheadings)
    dummy_fields = self.opts.get('dummy_fields', None)
    if dummy_fields:
        self._insert_dummy_fields(dummy_fields)
    formname = ('%s/%s' % (tablename, record_id))
    post_vars = request.post_vars
    if form.accepts(post_vars, current.session, onvalidation=self.validate, formname=formname, keepvalues=False, hideerror=False):
        if post_vars.get('_undelete'):
            undelete = (post_vars.get('deleted') is False)
        else:
            undelete = False
        link = options.get('link')
        hierarchy = options.get('hierarchy')
        self.accept(form, format=format, link=link, hierarchy=hierarchy, undelete=undelete)
        postprocess = self.opts.get('postprocess', None)
        if postprocess:
            try:
                callback(postprocess, form, tablename=tablename)
            except:
                error = ('postprocess    failed:    %s' % postprocess)
                current.log.error(error)
                raise
        response.confirmation = message
    if form.errors:
        db.rollback()
        response.error = current.T('There    are    errors    in    the    form,    please    check    your    input')
    return form
