src/YamlDefinitionLoader.php
private function parseDefinition($id, $service)
    {
        if (is_string($service) && 0 === strpos($service, '@')) {
            return new Reference(substr($service, 1));
        }

        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" in %s. Check your YAML syntax.', gettype($service), $id, $this->fileName));
        }

        if (isset($service['alias'])) {
            if (isset($service['public'])) {
                throw new InvalidArgumentException('The "public" key is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
            }

            return new Reference($service['alias']);
        }

        if (isset($service['parent'])) {
            throw new InvalidArgumentException('Definition decorators via the "parent" key are not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        $definition = null;

        if (isset($service['class'])) {
            $definition = new ObjectDefinition($service['class']);

            if (isset($service['arguments'])) {
                $arguments = $this->resolveServices($service['arguments']);
                foreach ($arguments as $argument) {
                    $definition->addConstructorArgument($argument);
                }
            }

            if (isset($service['properties'])) {
                $properties = $this->resolveServices($service['properties']);
                foreach ($properties as $name => $property) {
                    $definition->addPropertyAssignment($name, $property);
                }
            }

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

                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();
                    }

                    array_unshift($args, $method);
                    call_user_func_array([$definition, 'addMethodCall'], $args);
                }
            }
        }

        if (isset($service['factory'])) {
            if (is_string($service['factory'])) {
                if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
                    $parts = explode(':', $service['factory']);
                    $definition = new FactoryCallDefinition($this->resolveServices('@'.$parts[0]), $parts[1]);
                } elseif (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') !== false) {
                    $parts = explode('::', $service['factory']);
                    $definition = new FactoryCallDefinition($parts[0], $parts[1]);
                } else {
                    throw new InvalidArgumentException('A "factory" must be in the format "service_name:method_name" or "class_name::method_name".Got "'.$service['factory'].'"');
                }
            } else {
                $definition = new FactoryCallDefinition($this->resolveServices($service['factory'][0]), $service['factory'][1]);
            }

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

        if (isset($service['shared'])) {
            throw new InvalidArgumentException('The "shared" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['synthetic'])) {
            throw new InvalidArgumentException('The "synthetic" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['lazy'])) {
            throw new InvalidArgumentException('The "lazy" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['public'])) {
            // TODO: add support for private services => mapping to nested definitions
            throw new InvalidArgumentException('The "public" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['abstract'])) {
            throw new InvalidArgumentException('The "abstract" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (array_key_exists('deprecated', $service)) {
            throw new InvalidArgumentException('The "deprecated" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['file'])) {
            throw new InvalidArgumentException('The "file" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['configurator'])) {
            throw new InvalidArgumentException('The "configurator" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['tags'])) {
            throw new InvalidArgumentException('The "tags" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['decorates'])) {
            throw new InvalidArgumentException('The "decorates" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['autowire'])) {
            throw new InvalidArgumentException('The "autowire" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['autowiring_types'])) {
            throw new InvalidArgumentException('The "autowiring_types" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if ($definition === null) {
            throw new InvalidArgumentException(sprintf('Invalid service declaration for "%s" (in %s). You should specify at least a "class", "alias" or "factory" key.', $id, $this->fileName));
        }

        return $definition;
    }
private function parseDefinition($id, $service)
    {
        if (is_string($service) && 0 === strpos($service, '@')) {
            return new Reference(substr($service, 1));
        }

        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" in %s. Check your YAML syntax.', gettype($service), $id, $this->fileName));
        }

        if (isset($service['alias'])) {
            if (isset($service['public'])) {
                throw new InvalidArgumentException('The "public" key is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
            }

            return new Reference($service['alias']);
        }

        if (isset($service['parent'])) {
            throw new InvalidArgumentException('Definition decorators via the "parent" key are not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        $definition = null;

        if (isset($service['class'])) {
            $definition = new ObjectDefinition($service['class']);

            if (isset($service['arguments'])) {
                $arguments = $this->resolveServices($service['arguments']);
                foreach ($arguments as $argument) {
                    $definition->addConstructorArgument($argument);
                }
            }

            if (isset($service['properties'])) {
                $properties = $this->resolveServices($service['properties']);
                foreach ($properties as $name => $property) {
                    $definition->addPropertyAssignment($name, $property);
                }
            }

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

                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();
                    }

                    array_unshift($args, $method);
                    call_user_func_array([$definition, 'addMethodCall'], $args);
                }
            }
        }

        if (isset($service['factory'])) {
            if (is_string($service['factory'])) {
                if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
                    $parts = explode(':', $service['factory']);
                    $definition = new FactoryCallDefinition($this->resolveServices('@'.$parts[0]), $parts[1]);
                } elseif (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') !== false) {
                    $parts = explode('::', $service['factory']);
                    $definition = new FactoryCallDefinition($parts[0], $parts[1]);
                } else {
                    throw new InvalidArgumentException('A "factory" must be in the format "service_name:method_name" or "class_name::method_name".Got "'.$service['factory'].'"');
                }
            } else {
                $definition = new FactoryCallDefinition($this->resolveServices($service['factory'][0]), $service['factory'][1]);
            }

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

        if (isset($service['shared'])) {
            throw new InvalidArgumentException('The "shared" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['synthetic'])) {
            throw new InvalidArgumentException('The "synthetic" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['lazy'])) {
            throw new InvalidArgumentException('The "lazy" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['public'])) {
            // TODO: add support for private services => mapping to nested definitions
            throw new InvalidArgumentException('The "public" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['abstract'])) {
            throw new InvalidArgumentException('The "abstract" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (array_key_exists('deprecated', $service)) {
            throw new InvalidArgumentException('The "deprecated" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['file'])) {
            throw new InvalidArgumentException('The "file" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['configurator'])) {
            throw new InvalidArgumentException('The "configurator" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['tags'])) {
            throw new InvalidArgumentException('The "tags" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['decorates'])) {
            throw new InvalidArgumentException('The "decorates" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['autowire'])) {
            throw new InvalidArgumentException('The "autowire" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if (isset($service['autowiring_types'])) {
            throw new InvalidArgumentException('The "autowiring_types" key in instance definitions is not supported by YamlDefinitionLoader. This is a Symfony specific feature.');
        }

        if ($definition === null) {
            throw new InvalidArgumentException(sprintf('Invalid service declaration for "%s" (in %s). You should specify at least a "class", "alias" or "factory" key.', $id, $this->fileName));
        }

        return $definition;
    }
Parses a definition.

@param string $id
@param array  $service

@return DefinitionInterface

@throws InvalidArgumentException When tags are invalid