public function declareField(string $field, string $type, string $source, string $origin = null)
    {
        $schema = $this->constant('SCHEMA')->getValue();
        $setters = $this->constant('SETTERS')->getValue();
        $validates = $this->constant('VALIDATES')->getValue();

        if (!isset($this->mapping[$type])) {
            $schema[$field] = $source . ':' . ($origin ? $origin : $field);

            $this->constant('SCHEMA')->setValue($schema);

            return;
        }

        $definition = $this->mapping[$type];

        //Source can depend on type
        $source = $definition['source'];
        $schema[$field] = $source . ':' . ($origin ? $origin : $field);

        if (!empty($definition['setter'])) {
            //Pre-defined setter
            $setters[$field] = $definition['setter'];
        }

        if (!empty($definition['validates'])) {
            //Pre-defined validation
            $validates[$field] = $definition['validates'];
        }

        $this->constant('SCHEMA')->setValue($schema);
        $this->constant('SETTERS')->setValue($setters);
        $this->constant('VALIDATES')->setValue($validates);
    }