Customise a custom product attribute input renderer in Magento 2 the right way

TL;DR: If you need to customise your custom attribute in product edit form Magento 2, use PHP modifier in UI components instead of input renderer.

I found the solution myself.

As we all knew that Magento 2 using UI components, the solution I'm talking about here is PHP modifier in UI components.

From Magento 2 devdocs:

PHP modifiers that are the server-side part of UI components configuration. Using modifiers is optional and might be necessary when static declaration in XML configuration files is not suitable for the tasks. For example, in cases when additional data should be loaded from database. Or the other specific example is the default product creation form, for which the modifier is a place where validations are added to display only certain fields for certain product types.

By default, Magento 2 using PHP modifiers to render EAV attribute. They never use input_renderer to do so. If you are reading here, I assume that you need few examples, so here you are :)

Ui\DataProviders\Product\Form\Modifier\CustomAttr

<?php
namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier;

use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\Form\Field;

/**
 * Data provider for "Custom Attribute" field of product page
 */
class CustomAttr extends AbstractModifier
{
    const SUGGEST_FILTER_URI = 'vendor_module/something/suggestCustomAttr';

    /**
     * @param LocatorInterface            $locator
     * @param UrlInterface                $urlBuilder
     * @param ArrayManager                $arrayManager
     */
    public function __construct(
        LocatorInterface $locator,
        UrlInterface $urlBuilder,
        ArrayManager $arrayManager
    ) {
        $this->locator = $locator;
        $this->urlBuilder = $urlBuilder;
        $this->arrayManager = $arrayManager;
    }

    /**
     * {@inheritdoc}
     */
    public function modifyMeta(array $meta)
    {
        $meta = $this->customiseCustomAttrField($meta);

        return $meta;
    }

    /**
     * {@inheritdoc}
     */
    public function modifyData(array $data)
    {
        return $data;
    }

    /**
     * Customise Custom Attribute field
     *
     * @param array $meta
     *
     * @return array
     */
    protected function customiseCustomAttrField(array $meta)
    {
        $fieldCode = 'custom_ids'; //your custom attribute code
        $elementPath = $this->arrayManager->findPath($fieldCode, $meta, null, 'children');
        $containerPath = $this->arrayManager->findPath(static::CONTAINER_PREFIX . $fieldCode, $meta, null, 'children');

        if (!$elementPath) {
            return $meta;
        }

        $meta = $this->arrayManager->merge(
            $containerPath,
            $meta,
            [
                'arguments' => [
                    'data' => [
                        'config' => [
                            'label'         => __('Custom Attribute'),
                            'dataScope'     => '',
                            'breakLine'     => false,
                            'formElement'   => 'container',
                            'componentType' => 'container',
                            'component'     => 'Magento_Ui/js/form/components/group',
                            'scopeLabel'    => __('[GLOBAL]'),
                        ],
                    ],
                ],
                'children'  => [
                    $fieldCode => [
                        'arguments' => [
                            'data' => [
                                'config' => [
                                    'component'     => 'Vendor_Module/js/components/your-select-js',
                                    'componentType' => Field::NAME,
                                    'formElement'   => 'select',
                                    'elementTmpl'   => 'ui/grid/filters/elements/ui-select',
                                    'disableLabel'  => true,
                                    'multiple'      => false,
                                    'options'       => $this->getOptions(),
                                    'filterUrl'     => $this->urlBuilder->getUrl(
                                        self::SUGGEST_FILTER_URI,
                                        ['isAjax' => 'true']
                                    ),
                                    'config'           => [
                                        'dataScope' => $fieldCode,
                                        'sortOrder' => self::FIELD_ORDER,
                                    ],
                                ],
                            ],
                        ],
                    ]
                ]
            ]
        );

        return $meta;
    }

    /**
     * Retrieve custom attribute collection
     *
     * @return array
     */
    protected function getOptions()
    {
        // Get your options
    }
}

etc/adminhtml/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="custom-attribute" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\CustomAttr</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

Above is example of two important file which ping Magento 2 to render your custom attribute fields in product edit form to whatever you want. You will need to customise with javascript if you want it plays smoothly.

And yes, welcome to Magento 2 most painful's world - UI components.