public function compileAnnotations()
 {
     $cache_class = new \Symforce\CoreBundle\PhpHelper\PhpClass();
     $cache_class->setName('Symforce\\Builder\\SymforceAnnotationCache')->setFinal(true)->setParentClassName('Symforce\\CoreBundle\\Annotation\\SymforceAnnotationCache');
     $base_parent_class = sprintf('%s\\SymforceAbstractAnnotation', __NAMESPACE__);
     /**
      * @var $class_builder SymforceAnnotationClassBuilder
      */
     foreach ($this->class_builders as $annotation_name => $class_builder) {
         $_parents = array();
         if ($this->hasParentsLoop($class_builder, $_parents)) {
             throw new \Exception(sprintf("services(tag:{name:%s}) parent circular dependencies: %s ! ", self::CLASS_TAG_NAME, join(',', array_map(function (SymforceAnnotationBuilder $builder) {
                 return sprintf("\n\t,service(%s, tag{alias:%s%s})", $class_builder->getId(), $class_builder->getName(), $class_builder->getParentName() ? ', parent:' . $class_builder->getParentName() : '');
             }, $_parents))));
         }
         $_properties = $class_builder->getProperties();
         $_public_properties = $class_builder->getPublicProperties();
         if ($_public_properties) {
             foreach ($_public_properties as $_public_property_name) {
                 if (!isset($this->public_properties[$_public_property_name])) {
                     throw new \Exception(sprintf("service(%s, tags:{name: %s, alias: %s, properties: %s}) property(%s) must be one of (%s)", $class_builder->getId(), self::CLASS_TAG_NAME, $class_builder->getName(), var_export($_public_properties, 1), var_export($_public_property_name, 1), join(',', array_keys($this->public_properties))));
                 }
             }
         }
         $value_property_name = $class_builder->getValuePropertyName();
         if ($value_property_name) {
             if ($_public_properties) {
                 $_all_properties = array_unique(array_merge(array_keys($_properties), $_public_properties));
             } else {
                 $_all_properties = $_properties;
             }
             if (!$class_builder->hasPropertyBuilder($value_property_name) && !isset($this->public_properties[$value_property_name])) {
                 throw new \Exception(sprintf("service(%s, tags:{name: %s, alias: %s, value: %s}) value must be one of(%s)", $class_builder->getId(), self::CLASS_TAG_NAME, $class_builder->getName(), $value_property_name, join(',', $_all_properties)));
             }
         } else {
             if ($class_builder->getValueNotNull() || $class_builder->getValueAsKey()) {
                 throw new \Exception(sprintf("service(%s, tags:{name:%s, alias:%s}) tag.value is required", $class_builder->getId(), self::CLASS_TAG_NAME, $class_builder->getName()));
             }
         }
         $annotation_camelize_name = $class_builder->getCamelizeName();
         $class = new \Symforce\CoreBundle\PhpHelper\PhpClass($this->getAnnotationClassName($annotation_camelize_name));
         $parent_name = $class_builder->getParentName();
         if ($parent_name) {
             $class->setParentClassName($this->getAnnotationClassName($parent_name));
         } else {
             $class->setParentClassName($base_parent_class);
         }
         $class->setConstant('SYMFORCE_ANNOTATION_NAME', $annotation_name);
         $group_id = $class_builder->getGroupId();
         if (null !== $group_id) {
             $class->setConstant('SYMFORCE_ANNOTATION_GROUP_ID', $group_id);
         }
         $value_property_name = $class_builder->getValuePropertyName();
         if ($value_property_name) {
             $class->setConstant('SYMFORCE_ANNOTATION_VALUE_AS_PROPERTY', $value_property_name);
         }
         if ($class_builder->getValueAsKey()) {
             $class->setConstant('SYMFORCE_ANNOTATION_VALUE_AS_KEY', 1);
         }
         if ($class_builder->getValueNotNull()) {
             $class->setConstant('SYMFORCE_ANNOTATION_VALUE_NOT_NULL', 1);
         }
         $doc = sprintf(" * @Annotation");
         $annotation_target = $class_builder->getTarget();
         if (!$annotation_target) {
             $annotation_target = array('CLASS', 'PROPERTY');
         }
         $doc .= sprintf("\n * @Target({\"") . join('","', $annotation_target) . sprintf("\"})");
         $class->setDocblock($doc);
         if (in_array('CLASS', $annotation_target)) {
             $cache_class->addMethod('get' . $annotation_camelize_name . 'ClassAnnotation', true)->setDocblock('/* @return \\' . $class->getName() . ' */')->getWriter()->writeln(sprintf('return $this->getClassValue("%s");', $class_builder->getName()));
             if ($class_builder->getValueAsKey()) {
                 $cache_class->addMethod('get' . $annotation_camelize_name . 'ClassValues', true)->setDocblock('/* @return array(\\' . $class->getName() . ') */')->getWriter()->writeln(sprintf('return $this->getClassValue("%s", true);', $class_builder->getName()));
             }
         }
         if (in_array('PROPERTY', $annotation_target)) {
             $cache_class->addMethod('get' . $annotation_camelize_name . 'PropertyAnnotation', true)->addParameter(\CG\Generator\PhpParameter::create('property_name'))->setDocblock('/* @return \\' . $class->getName() . ' */')->getWriter()->writeln(sprintf('return $this->getPropertyValue($property_name, "%s");', $class_builder->getName()));
             if ($class_builder->getValueAsKey()) {
                 $cache_class->addMethod('get' . $annotation_camelize_name . 'PropertyValues', true)->addParameter(\CG\Generator\PhpParameter::create('property_name'))->setDocblock('/* @return array(\\' . $class->getName() . ') */')->getWriter()->writeln(sprintf('return $this->getPropertyValue($property_name, "%s", true);', $class_builder->getName()));
             }
         }
         $value_property_name = null;
         /**
          * @var $property_builder SymforceAnnotationPropertyBuilder
          */
         if ($_public_properties) {
             foreach ($_public_properties as $property_name) {
                 if (!isset($_properties[$property_name])) {
                     $property_builder = $this->public_properties[$property_name];
                     $type = $property_builder->getType();
                     if (!$type) {
                         $type = 'string';
                     }
                     $class->addProperty($property_name, null, $type, false, true);
                 }
             }
         }
         foreach ($_properties as $property_name => $property_builder) {
             $type = $property_builder->getType();
             if (!$type) {
                 $type = 'string';
             }
             $class->addProperty($property_name, null, $type, false, true);
         }
         $class->writeCache();
     }
     $cache_class->writeCache();
 }
 public function compileEvents()
 {
     $base_parent_class = sprintf('%s\\SymforceAbstractEvent', __NAMESPACE__);
     /**
      * @var $class_builder SymforceEventBuilder
      */
     foreach ($this->_events as $event_name => $class_builder) {
         $_parents = array();
         if ($this->hasParentsLoop($class_builder, $_parents)) {
             throw new \Exception(sprintf("services(tag:{name:%s}) parent circular dependencies: %s ! ", self::TAG_NAME, join(',', array_map(function (SymforceAnnotationBuilder $builder) {
                 return sprintf("\n\t,service(%s, tag{alias:%s%s})", $builder->getId(), $this->getName(), $builder->getParentName() ? ', parent:' . $builder->getParentName() : '');
             }, $_parents))));
         }
         $class = new \Symforce\CoreBundle\PhpHelper\PhpClass($this->getClassName($event_name));
         $parent_name = $class_builder->getParentName();
         if ($parent_name) {
             $class->setParentClassName($this->getClassName($parent_name));
         } else {
             $class->setParentClassName($base_parent_class);
         }
         /**
          * @var $property_builder SymforceEventArgsBuilder
          */
         foreach ($class_builder->getEventArgumentBuilders() as $property_name => $property_builder) {
             $type = $property_builder->getType();
             if (!$type) {
                 $type = 'string';
             }
             $class->addProperty($property_name, null, $type, false, true);
         }
         $class->writeCache();
     }
 }