Parses a definition.

@param string $id
@param array  $service

@throws InvalidArgumentException When tags are invalid

@link https://github.com/symfony/DependencyInjection/blob/v2.7.0/Loader/YamlFileLoader.php#L137
359738
private function parseDefinition($id, $service)
    {
        if (is_string($service) && 0 === strpos($service, '@')) {
            $this->container->setAlias($id, substr($service, 1));

            return;
        }

        if (!is_array($service)) {
            throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s". Check your YAML syntax.', gettype($service), $id));
        }

        if (isset($service['alias'])) {
            $public = !array_key_exists('public', $service) || (bool) $service['public'];
            $this->container->setAlias($id, new Alias($service['alias'], $public));

            return;
        }

        if (isset($service['parent'])) {
            $definition = new DefinitionDecorator($service['parent']);
        } else {
            $definition = new Definition();
        }

        if (isset($service['class'])) {
            $definition->setClass($service['class']);
        }

        if (isset($service['scope'])) {
            $definition->setScope($service['scope']);
        }

        if (isset($service['synthetic'])) {
            $definition->setSynthetic($service['synthetic']);
        }

        if (isset($service['synchronized'])) {
            $definition->setSynchronized($service['synchronized'], 'request' !== $id);
        }

        if (isset($service['lazy'])) {
            $definition->setLazy($service['lazy']);
        }

        if (isset($service['public'])) {
            $definition->setPublic($service['public']);
        }

        if (isset($service['abstract'])) {
            $definition->setAbstract($service['abstract']);
        }

        if (isset($service['factory'])) {
            if (is_string($service['factory'])) {
                if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
                    $parts = explode(':', $service['factory']);
                    $definition->setFactory(array($this->resolveServices('@'.$parts[0]), $parts[1]));
                } else {
                    $definition->setFactory($service['factory']);
                }
            } else {
                $definition->setFactory(array($this->resolveServices($service['factory'][0]), $service['factory'][1]));
            }
        }

        if (isset($service['factory_class'])) {
            $definition->setFactoryClass($service['factory_class']);
        }

        if (isset($service['factory_method'])) {
            $definition->setFactoryMethod($service['factory_method']);
        }

        if (isset($service['factory_service'])) {
            $definition->setFactoryService($service['factory_service']);
        }

        if (isset($service['file'])) {
            $definition->setFile($service['file']);
        }

        if (isset($service['arguments'])) {
            $definition->setArguments($this->resolveServices($service['arguments']));
        }

        if (isset($service['properties'])) {
            $definition->setProperties($this->resolveServices($service['properties']));
        }

        if (isset($service['configurator'])) {
            if (is_string($service['configurator'])) {
                $definition->setConfigurator($service['configurator']);
            } else {
                $definition->setConfigurator(array($this->resolveServices($service['configurator'][0]), $service['configurator'][1]));
            }
        }

        if (isset($service['calls'])) {
            if (!is_array($service['calls'])) {
                throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s". Check your YAML syntax.', $id));
            }
            foreach ($service['calls'] as $call) {
                if (isset($call['method'])) {
                    $method = $call['method'];
                    $args = isset($call['arguments']) ? $this->resolveServices($call['arguments']) : array();
                } else {
                    $method = $call[0];
                    $args = isset($call[1]) ? $this->resolveServices($call[1]) : array();
                }
                $definition->addMethodCall($method, $args);
            }
        }

        if (isset($service['tags'])) {
            if (!is_array($service['tags'])) {
                throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s". Check your YAML syntax.', $id));
            }

            foreach ($service['tags'] as $tag) {
                if (!is_array($tag)) {
                    throw new InvalidArgumentException(sprintf('A "tags" entry must be an array for service "%s". Check your YAML syntax.', $id));
                }
                if (!isset($tag['name'])) {
                    throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s".', $id));
                }
                $name = $tag['name'];
                unset($tag['name']);
                foreach ($tag as $attribute => $value) {
                    if (!is_scalar($value) && null !== $value) {
                        throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s". Check your YAML syntax.', $id, $name, $attribute));
                    }
                }
                $definition->addTag($name, $tag);
            }
        }

        if (isset($service['decorates'])) {
            $renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null;
            $definition->setDecoratedService($service['decorates'], $renameId);
        }

        $this->container->setDefinition($id, $definition);
    }
1043673
public function getDefinition($id)
    {
        $id = $this->normalizeId($id);

        if (!isset($this->definitions[$id])) {
            throw new ServiceNotFoundException($id);
        }

        return $this->definitions[$id];
    }
330664
private function parseServicesSettings(\DOMNode $services) {

		if(is_null($this->services)) {
			$this->services = [];
		}

		foreach($services->getElementsByTagName('service') as $service) {

			if(!($id = $service->getAttribute('id'))) {
				throw new ConfigException('Service without id found.');
			}

			if(isset($this->services[$id])) {
				throw new ConfigException(sprintf("Service '%s' has already been defined.", $id));
			}

			if(!($class = $service->getAttribute('class'))) {
				throw new ConfigException(sprintf("No class for service '%s' configured.", $id));
			}

			// clean path delimiters, prepend leading backslash, and replace slashes with backslashes

			$class = '\\' . ltrim(str_replace('/', '\\', $class), '/\\');

			// store parsed information

			$this->services[$id] = [
				'class'			=> $class,
				'parameters'	=> []
			];

			foreach($service->getElementsByTagName('parameter') as $parameter) {

				$name = $parameter->getAttribute('name');
				$value = $parameter->getAttribute('value');

				if(!$name) {
					throw new ConfigException(sprintf("A parameter for service '%s' has no name.", $id));
				}

				$this->services[$id]['parameters'][$name] = $value;

			}

		}

	}
1150969
public function addRunnerService($name, $id, array $options = array())
    {
        if (!$this->container->has($id)) {
            throw new InvalidArgumentException("Service container does not have required service registered.");
        }
        $this->runnerServices[$name] = array(
            'id' => $id,
            'options' => $options,
        );
    }
1014361
private function findAndReplaceTaggedServices($id, array $service, ContainerBuilder $container)
    {
        $serviceConfig = $this->createServiceConfig($id, $service);

        if ($serviceConfig->has(ServiceConfig::CONTAINER)) {
            $replace = $this->getDefinitionsAsContainer($container, $serviceConfig);
        } else {
            $replace = $this->getDefinitionsAsArray($container, $serviceConfig);
        }

        $definition = $container->findDefinition($id);
        $definition->replaceArgument($this->findArgumentToReplace($definition, $serviceConfig), $replace);
    }
55136
private function addService($id, Definition $definition)
    {
        $code = "    $id:\n";
        if ($class = $definition->getClass()) {
            if ('\\' === substr($class, 0, 1)) {
                $class = substr($class, 1);
            }

            $code .= sprintf("        class: %s\n", $this->dumper->dump($class));
        }

        if (!$definition->isPrivate()) {
            $code .= sprintf("        public: %s\n", $definition->isPublic() ? 'true' : 'false');
        }

        $tagsCode = '';
        foreach ($definition->getTags() as $name => $tags) {
            foreach ($tags as $attributes) {
                $att = array();
                foreach ($attributes as $key => $value) {
                    $att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value));
                }
                $att = $att ? ', '.implode(', ', $att) : '';

                $tagsCode .= sprintf("            - { name: %s%s }\n", $this->dumper->dump($name), $att);
            }
        }
        if ($tagsCode) {
            $code .= "        tags:\n".$tagsCode;
        }

        if ($definition->getFile()) {
            $code .= sprintf("        file: %s\n", $this->dumper->dump($definition->getFile()));
        }

        if ($definition->isSynthetic()) {
            $code .= "        synthetic: true\n";
        }

        if ($definition->isDeprecated()) {
            $code .= sprintf("        deprecated: %s\n", $definition->getDeprecationMessage('%service_id%'));
        }

        if ($definition->isAutowired()) {
            $code .= "        autowire: true\n";
        }

        $autowiringTypesCode = '';
        foreach ($definition->getAutowiringTypes(false) as $autowiringType) {
            $autowiringTypesCode .= sprintf("            - %s\n", $this->dumper->dump($autowiringType));
        }
        if ($autowiringTypesCode) {
            $code .= sprintf("        autowiring_types:\n%s", $autowiringTypesCode);
        }

        if ($definition->isAutoconfigured()) {
            $code .= "        autoconfigure: true\n";
        }

        if ($definition->isAbstract()) {
            $code .= "        abstract: true\n";
        }

        if ($definition->isLazy()) {
            $code .= "        lazy: true\n";
        }

        if ($definition->getArguments()) {
            $code .= sprintf("        arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0));
        }

        if ($definition->getProperties()) {
            $code .= sprintf("        properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0));
        }

        if ($definition->getMethodCalls()) {
            $code .= sprintf("        calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12));
        }

        if (!$definition->isShared()) {
            $code .= "        shared: false\n";
        }

        if (null !== $decorated = $definition->getDecoratedService()) {
            list($decorated, $renamedId, $priority) = $decorated;
            $code .= sprintf("        decorates: %s\n", $decorated);
            if (null !== $renamedId) {
                $code .= sprintf("        decoration_inner_name: %s\n", $renamedId);
            }
            if (0 !== $priority) {
                $code .= sprintf("        decoration_priority: %s\n", $priority);
            }
        }

        if ($callable = $definition->getFactory()) {
            $code .= sprintf("        factory: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
        }

        if ($callable = $definition->getConfigurator()) {
            $code .= sprintf("        configurator: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
        }

        return $code;
    }
1040195
public function addService(DataTableHandlerInterface $service, string $id = null)
    {
        $service_id = $id ?? $service::ID;

        if ($service_id !== null) {
            $this->services[$service_id] = $service;
        }
    }
880546
private function getServiceOrParameter($id)
    {
        if (array_key_exists($id, $this->aliases)) {
            return $this->offsetGet($this->aliases[$id]);
        }

        if (array_key_exists($id, $this->values)) {
            return $this->values[$id];
        }

        if (array_key_exists($id, $this->definitions)) {
            return $this->values[$id] = $this->build($this->definitions[$id]);
        }

        throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
    }
222354
private function getDefinitionId($id)
    {
        $seen = array();
        while ($this->container->hasAlias($id)) {
            if (isset($seen[$id])) {
                throw new ServiceCircularReferenceException($id, array_keys($seen));
            }
            $seen[$id] = true;
            $id = (string) $this->container->getAlias($id);
        }

        return $id;
    }
45918
protected function getAttribute($id, array $attributes, $attribute)
    {
        if (isset($attributes[$attribute])) {
            return $attributes[$attribute];
        }

        throw new \InvalidArgumentException(sprintf(
            'Service "%s" must define the "%s" attribute on "%s" tags.',
            $id, $attribute, $this->tagName
        ));
    }
1366544
private function checkDefinition($id, array $definition, $file)
    {
        if ($throw = $this->isLoadingInstanceof) {
            $keywords = self::$instanceofKeywords;
        } elseif ($throw = (isset($definition['resource']) || isset($definition['namespace']))) {
            $keywords = self::$prototypeKeywords;
        } else {
            $keywords = self::$serviceKeywords;
        }

        foreach ($definition as $key => $value) {
            if (!isset($keywords[$key])) {
                if ($throw) {
                    throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, implode('", "', $keywords)));
                }

                @trigger_error(sprintf('The configuration key "%s" is unsupported for service definition "%s" in "%s". Allowed configuration keys are "%s". The YamlFileLoader object will raise an exception instead in Symfony 4.0 when detecting an unsupported service configuration key.', $key, $id, $file, implode('", "', $keywords)), E_USER_DEPRECATED);
            }
        }
    }
847391
public function getAlias($id)
    {
        $id = $this->normalizeId($id);

        if (!isset($this->aliasDefinitions[$id])) {
            throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
        }

        return $this->aliasDefinitions[$id];
    }
636564
private function getDefinitionId($id, ContainerBuilder $container)
    {
        $seen = array();
        while ($container->hasAlias($id)) {
            if (isset($seen[$id])) {
                throw new ServiceCircularReferenceException($id, array_keys($seen));
            }
            $seen[$id] = true;
            $id = $container->normalizeId($container->getAlias($id));
        }

        return $id;
    }
1081690
public function getDefinition($id) {
		if (isset($this->_definitions[$id])) {
			return $this->_definitions[$id];
		}
		
		$locator = $this->getLocatorByServiceId($id);
		
		if ($locator !== null) {
			if ($locator instanceof DefinitionAwareInterface) {
				$definition = $locator->getDefinition($id);
				
				$this->_definitions[$id] = $definition;
				return $definition;
			}
			
			throw new Exceptions\ServiceNotFound('Unable to provide definition for the service "' . $id . '"');
		}
		
		throw new Exceptions\ServiceNotFound('Unable to found the service "' . $id . '"');
	}
784539
private function addServiceInstance($id, Definition $definition, $isSimpleInstance)
    {
        $class = $this->dumpValue($definition->getClass());

        if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
            throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id));
        }

        $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
        $instantiation = '';

        if (!$isProxyCandidate && $definition->isShared()) {
            $instantiation = "\$this->services['$id'] = ".($isSimpleInstance ? '' : '$instance');
        } elseif (!$isSimpleInstance) {
            $instantiation = '$instance';
        }

        $return = '';
        if ($isSimpleInstance) {
            $return = 'return ';
        } else {
            $instantiation .= ' = ';
        }

        $code = $this->addNewInstance($definition, $return, $instantiation, $id);

        if (!$isSimpleInstance) {
            $code .= "\n";
        }

        return $code;
    }
1198009
public function bind($id, $definition = [], $replace = true)
    {
        $container = Container::$instance;
        if (!$replace && $container->has($id)) {
            throw new InvalidParamException("Can not bind service, service '$id' is already exists.");
        }

        if (is_array($definition) && !isset($definition['class'])) {
            throw new InvalidConfigException("The configuration for the \"$id\" service must contain a \"class\" element.");
        }

        $container->setSingleton($id, $definition);
    }
1071506
protected function validate(ApiServiceInterface $service)
    {
        $validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator();
        $violations = $validator->validate($service);
        /** @var ConstraintViolation $violation */
        foreach ($violations as $violation) {
            $errorMessage = $violation->getMessage();
            if ($violation->getPropertyPath()) {
                $errorMessage = sprintf('Error in field "%s": ', $violation->getPropertyPath()) . $errorMessage;
            }
            throw new InvalidApiDataException($errorMessage);
        }
    }