public function run($language, CompileOptions $options)
    {
        $namespaces = $options->getNamespaces();

        if (!$namespaces || count($namespaces) === 0) {
            throw new \InvalidArgumentException('Missing "namespaces" options.');
        }

        if (!is_array($namespaces)) {
            $namespaces = [$namespaces];
        }

        foreach ($namespaces as $namespace) {
            if (!preg_match('/^([a-z0-9-]+):([a-z0-9\.-]+)$/', $namespace)) {
                throw new \InvalidArgumentException(sprintf(
                    'The namespace "%s" must follow "vendor:package" format.',
                    $namespace
                ));
            }
        }

        if (!$options->getOutput()) {
            throw new \InvalidArgumentException('Missing "output" directory options.');
        }

        $class = sprintf('\Gdbots\Pbjc\Generator\%sGenerator', StringUtils::toCamelFromSlug($language));

        /** @var Generator $generator */
        $generator = new $class($options);
        $outputFiles = [];

        foreach (SchemaStore::getEnums() as $enum) {
            if (!$options->getIncludeAll() && !in_array($enum->getId()->getNamespace(), $namespaces)) {
                continue;
            }

            $outputFiles = array_merge($outputFiles, $generator->generateEnum($enum)->getFiles());
        }

        foreach (SchemaStore::getSchemas() as $schema) {
            if (!$options->getIncludeAll() && !in_array($schema->getId()->getNamespace(), $namespaces)) {
                continue;
            }

            $outputFiles = array_merge($outputFiles, $generator->generateSchema($schema)->getFiles());
        }

        $outputFiles = array_merge($outputFiles, $generator->generateManifest(SchemaStore::getSchemas())->getFiles());

        if ($callback = $options->getCallback()) {
            foreach ($outputFiles as $outputFile) {
                call_user_func($callback, $outputFile);
            }
        }
    }