Get a Graphql Enum configuration from given enum annotation.

@param string   $shortClassName
@param GQL\Enum $enumAnnotation
@param array    $classAnnotations
@param array    $constants

@return array
182290
private static function getGraphqlEnum(GQL\Enum $enumAnnotation, array $classAnnotations, array $constants)
    {
        $enumValues = $enumAnnotation->values ? $enumAnnotation->values : [];

        $values = [];

        foreach ($constants as $name => $value) {
            $valueAnnotation = \current(\array_filter($enumValues, function ($enumValueAnnotation) use ($name) {
                return $enumValueAnnotation->name == $name;
            }));
            $valueConfig = [];
            $valueConfig['value'] = $value;

            if ($valueAnnotation && $valueAnnotation->description) {
                $valueConfig['description'] = $valueAnnotation->description;
            }

            if ($valueAnnotation && $valueAnnotation->deprecationReason) {
                $valueConfig['deprecationReason'] = $valueAnnotation->deprecationReason;
            }

            $values[$name] = $valueConfig;
        }

        $enumConfiguration = ['values' => $values];
        $enumConfiguration = self::getDescriptionConfiguration($classAnnotations) + $enumConfiguration;

        return ['type' => 'enum', 'config' => $enumConfiguration];
    }
987487
private final static function loadClass($fqcn)
    {
        $reflectionClass = new ReflectionClass($fqcn);
        $constants       = $reflectionClass->getConstants();

        foreach ($constants as $name => $value) {
            $instance = new $fqcn($fqcn, $name, $value);

            /* @var $instance Enum */
            if (is_callable([$instance, '__initEnum'])) {
                $instance->__initEnum();
            }

            $instanceConstructorName = '__' . $name;
            if (is_callable([$instance, $instanceConstructorName])) {
                $instance->$instanceConstructorName();
            }

            if (!isset(self::$instances[$fqcn])) {
                self::$instances[$fqcn] = [];
            }

            self::$instances[$fqcn][$name] = $instance;
        }
    }
11336
public static function get($enum)
    {
        if (null === self::$ClassNames) {
            self::generateNamespace();
            self::generateClassNamesArray();
        }

        if (!isset(self::$ClassNames[$enum])) {
            throw new \InvalidArgumentException('Invalid enum "'.$enum.'".');
        }

        $className = self::$Namespace.'\\'.self::$ClassNames[$enum];

        return new $className();
    }
898653
private static function getDescriptionConfiguration(array $annotations, bool $withDeprecation = false)
    {
        $config = [];
        $descriptionAnnotation = self::getFirstAnnotationMatching($annotations, 'Overblog\GraphQLBundle\Annotation\Description');
        if ($descriptionAnnotation) {
            $config['description'] = $descriptionAnnotation->value;
        }

        if ($withDeprecation) {
            $deprecatedAnnotation = self::getFirstAnnotationMatching($annotations, 'Overblog\GraphQLBundle\Annotation\Deprecated');
            if ($deprecatedAnnotation) {
                $config['deprecationReason'] = $deprecatedAnnotation->value;
            }
        }

        return $config;
    }
481096
private function classConstant($class_name, $colon_node, $class_constant) {
    $node = new ClassConstantLookupNode();
    $node->addChild($class_name, 'className');
    $node->mergeNode($colon_node);
    $node->addChild($class_constant, 'constantName');
    return $node;
  }
1138945
public static <T extends Enum<T>> T getElementValueEnum(AnnotationMirror anno, CharSequence name, Class<T> t, boolean useDefaults) {
        Symbol.VarSymbol vs = getElementValue(anno, name, Symbol.VarSymbol.class, useDefaults);
        T value = Enum.valueOf(t, vs.getSimpleName().toString());
        return value;
    }
1191235
public static function createByName($name)
    {
        $constants = static::getConstantsByName();

        if (!array_key_exists($name, $constants)) {
            throw new UnexpectedValueException("Name '{$name}' is not exists in the enum constants list " . get_called_class());
        }

        return new static($constants[$name]);
    }
391227
private static function detectConstants($class)
    {
        if (!isset(self::$constants[$class])) {
            $reflection = new ReflectionClass($class);
            $constants  = [];

            do {
                $scopeConstants = [];
                // Enumerators must be defined as public class constants
                foreach ($reflection->getReflectionConstants() as $reflConstant) {
                    if ($reflConstant->isPublic()) {
                        $scopeConstants[ $reflConstant->getName() ] = $reflConstant->getValue();
                    }
                }

                $constants = $scopeConstants + $constants;
            } while (($reflection = $reflection->getParentClass()) && $reflection->name !== __CLASS__);

            assert(
                self::noAmbiguousValues($constants),
                "Ambiguous enumerator values detected for {$class}"
            );

            self::$constants[$class] = $constants;
            self::$names[$class] = \array_keys($constants);
        }

        return self::$constants[$class];
    }
926328
public static FieldInfo of(Enum<?> enumValue) {
    try {
      FieldInfo result = FieldInfo.of(enumValue.getClass().getField(enumValue.name()));
      Preconditions.checkArgument(
          result != null, "enum constant missing @Value or @NullValue annotation: %s", enumValue);
      return result;
    } catch (NoSuchFieldException e) {
      // not possible
      throw new RuntimeException(e);
    }
  }
52372
@Override
	public EnumeratedConstant findConstantInScope(String currentScope, String constant)
    {
        int i = constant.indexOf('.');
        if (i == -1)
        {
            return null;
        }
        String className = constant.substring(0,i);
        String fieldName = constant.substring(i+1);
        List<String> constants = m_constants.get(className);
        if (constants == null)
        {
            return null;
        }
        if (constants.contains(fieldName))
        {
            return new EnumeratedConstant(m_xsdpackageName,className,fieldName);
        }
        return null;
    }
39785
public static function getMethodAnnotations($className, $methodName, $annotationClassName = null)
    {
        if(!isset(static::$annotations[$className]['Methods'][$methodName]))
        {
            return [];
        }
        if(null === $annotationClassName)
        {
            return static::$annotations[$className]['Methods'][$methodName];
        }
        else
        {
            $result = [];
            foreach(static::$annotations[$className]['Methods'][$methodName] as $annotation)
            {
                if($annotation instanceof $annotationClassName)
                {
                    $result[] = $annotation;
                }
            }
            return $result;
        }
    }
862028
private function convertClassAnnotationsToEntityClassMetadata(
        array $classAnnotations,
        ReflectionClass $reflectionClass,
        Mapping\ClassMetadata $parent
    ) {
        /** @var Annotation\Entity $entityAnnot */
        $entityAnnot   = $classAnnotations[Annotation\Entity::class];
        $classMetadata = new Mapping\ClassMetadata($reflectionClass->getName(), $parent);

        if ($entityAnnot->repositoryClass !== null) {
            $classMetadata->setCustomRepositoryClassName($entityAnnot->repositoryClass);
        }

        if ($entityAnnot->readOnly) {
            $classMetadata->asReadOnly();
        }

        // Evaluate @Table annotation
        if (isset($classAnnotations[Annotation\Table::class])) {
            /** @var Annotation\Table $tableAnnot */
            $tableAnnot = $classAnnotations[Annotation\Table::class];
            $table      = $this->convertTableAnnotationToTableMetadata($tableAnnot);

            $classMetadata->setTable($table);
        }

        // Evaluate @ChangeTrackingPolicy annotation
        if (isset($classAnnotations[Annotation\ChangeTrackingPolicy::class])) {
            /** @var Annotation\ChangeTrackingPolicy $changeTrackingAnnot */
            $changeTrackingAnnot = $classAnnotations[Annotation\ChangeTrackingPolicy::class];

            $classMetadata->setChangeTrackingPolicy(
                constant(sprintf('%s::%s', Mapping\ChangeTrackingPolicy::class, $changeTrackingAnnot->value))
            );
        }

        // Evaluate @EntityListeners annotation
        if (isset($classAnnotations[Annotation\EntityListeners::class])) {
            /** @var Annotation\EntityListeners $entityListenersAnnot */
            $entityListenersAnnot = $classAnnotations[Annotation\EntityListeners::class];

            foreach ($entityListenersAnnot->value as $listenerClassName) {
                if (! class_exists($listenerClassName)) {
                    throw Mapping\MappingException::entityListenerClassNotFound(
                        $listenerClassName,
                        $reflectionClass->getName()
                    );
                }

                $listenerClass = new ReflectionClass($listenerClassName);

                /** @var ReflectionMethod $method */
                foreach ($listenerClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
                    foreach ($this->getMethodCallbacks($method) as $callback) {
                        $classMetadata->addEntityListener($callback, $listenerClassName, $method->getName());
                    }
                }
            }
        }

        // Evaluate @HasLifecycleCallbacks annotation
        if (isset($classAnnotations[Annotation\HasLifecycleCallbacks::class])) {
            /** @var ReflectionMethod $method */
            foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
                foreach ($this->getMethodCallbacks($method) as $callback) {
                    $classMetadata->addLifecycleCallback($method->getName(), $callback);
                }
            }
        }

        // Evaluate @InheritanceType annotation
        if (isset($classAnnotations[Annotation\InheritanceType::class])) {
            /** @var Annotation\InheritanceType $inheritanceTypeAnnot */
            $inheritanceTypeAnnot = $classAnnotations[Annotation\InheritanceType::class];

            $classMetadata->setInheritanceType(
                constant(sprintf('%s::%s', Mapping\InheritanceType::class, $inheritanceTypeAnnot->value))
            );

            if ($classMetadata->inheritanceType !== Mapping\InheritanceType::NONE) {
                $discriminatorColumn = new Mapping\DiscriminatorColumnMetadata();

                // Evaluate @DiscriminatorColumn annotation
                if (isset($classAnnotations[Annotation\DiscriminatorColumn::class])) {
                    /** @var Annotation\DiscriminatorColumn $discriminatorColumnAnnot */
                    $discriminatorColumnAnnot = $classAnnotations[Annotation\DiscriminatorColumn::class];

                    $discriminatorColumn->setColumnName($discriminatorColumnAnnot->name);

                    if (! empty($discriminatorColumnAnnot->columnDefinition)) {
                        $discriminatorColumn->setColumnDefinition($discriminatorColumnAnnot->columnDefinition);
                    }

                    if (! empty($discriminatorColumnAnnot->type)) {
                        $discriminatorColumn->setType(Type::getType($discriminatorColumnAnnot->type));
                    }

                    if (! empty($discriminatorColumnAnnot->length)) {
                        $discriminatorColumn->setLength($discriminatorColumnAnnot->length);
                    }
                }

                if (empty($discriminatorColumn->getColumnName())) {
                    throw Mapping\MappingException::nameIsMandatoryForDiscriminatorColumns($reflectionClass->getName());
                }

                $classMetadata->setDiscriminatorColumn($discriminatorColumn);

                // Evaluate @DiscriminatorMap annotation
                if (isset($classAnnotations[Annotation\DiscriminatorMap::class])) {
                    /** @var Annotation\DiscriminatorMap $discriminatorMapAnnotation */
                    $discriminatorMapAnnotation = $classAnnotations[Annotation\DiscriminatorMap::class];
                    $discriminatorMap           = $discriminatorMapAnnotation->value;

                    $classMetadata->setDiscriminatorMap($discriminatorMap);
                }
            }
        }

        return $classMetadata;
    }
341603
static <T extends Enum<T>>
    T get( Class<T> clazz, int v ) {
        return get(clazz).constant(v);
    }
749723
private static function getGraphqlFieldsFromProviders(string $namespace, string $className, string $annotationName, string $targetType, bool $isRoot = false)
    {
        $fields = [];
        foreach (self::$providers as $className => $configuration) {
            $providerMethods = $configuration['methods'];
            $providerAnnotation = $configuration['annotation'];

            $filteredMethods = [];
            foreach ($providerMethods as $methodName => $config) {
                $annotations = $config['annotations'];

                $annotation = self::getFirstAnnotationMatching($annotations, \sprintf('Overblog\\GraphQLBundle\\Annotation\\%s', $annotationName));
                if (!$annotation) {
                    continue;
                }

                $annotationTarget = 'Query' === $annotationName ? $annotation->targetType : null;
                if (!$annotationTarget && $isRoot) {
                    $annotationTarget = $targetType;
                }

                if ($annotationTarget !== $targetType) {
                    continue;
                }

                $filteredMethods[$methodName] = $config;
            }

            $currentValue = \sprintf("service('%s')", self::formatNamespaceForExpression($className));
            $providerFields = self::getGraphqlFieldsFromAnnotations($namespace, $filteredMethods, false, true, $currentValue, $annotationName);
            foreach ($providerFields as $fieldName => $fieldConfig) {
                if ($providerAnnotation->prefix) {
                    $fieldName = \sprintf('%s%s', $providerAnnotation->prefix, $fieldName);
                }
                $fields[$fieldName] = $fieldConfig;
            }
        }

        return $fields;
    }
770155
private function getNotationTypeArray($notation, &$params)
    {
        if ($notation && $notation == array_values($notation)) {
            $params['Default'] = isset($notation[0]) ? $notation[0] : null;

            return 'enum';
        }

        return 'schema';
    }
182263
public static <T extends Enum<T> & RichEnum<T>> RichEnumConstants<T> richConstants(Class<T> theClass) {
        return new RichEnumConstants<>(theClass);
    }
665464
public static function getClassAnnotations($className, $annotationClassName = null)
    {
        if(!isset(static::$annotations[$className]['Class']))
        {
            return [];
        }
        if(null === $annotationClassName)
        {
            return static::$annotations[$className]['Class'];
        }
        else
        {
            $result = [];
            foreach(static::$annotations[$className]['Class'] as $annotation)
            {
                if($annotation instanceof $annotationClassName)
                {
                    $result[] = $annotation;
                }
            }
            return $result;
        }
    }