protected function getDescription(PropertyMetadata $item)
 {
     $ref = new \ReflectionClass($item->class);
     if ($item instanceof VirtualPropertyMetadata) {
         $extracted = $this->commentExtractor->getDocCommentText($ref->getMethod($item->getter));
     } else {
         $extracted = $this->commentExtractor->getDocCommentText($ref->getProperty($item->name));
     }
     return $extracted;
 }
 /**
  * Returns a new ApiDoc instance with more data.
  *
  * @param  ApiDoc            $annotation
  * @param  Route             $route
  * @param  \ReflectionMethod $method
  * @return ApiDoc
  */
 protected function extractData(ApiDoc $annotation, Route $route, \ReflectionMethod $method)
 {
     // create a new annotation
     $annotation = clone $annotation;
     // doc
     $annotation->setDocumentation($this->commentExtractor->getDocCommentText($method));
     // parse annotations
     $this->parseAnnotations($annotation, $route, $method);
     // route
     $annotation->setRoute($route);
     // input (populates 'parameters' for the formatters)
     if (null !== ($input = $annotation->getInput())) {
         $parameters = array();
         $normalizedInput = $this->normalizeClassParameter($input);
         $supportedParsers = array();
         foreach ($this->getParsers($normalizedInput) as $parser) {
             if ($parser->supports($normalizedInput)) {
                 $supportedParsers[] = $parser;
                 $parameters = $this->mergeParameters($parameters, $parser->parse($normalizedInput));
             }
         }
         foreach ($supportedParsers as $parser) {
             if ($parser instanceof PostParserInterface) {
                 $parameters = $this->mergeParameters($parameters, $parser->postParse($normalizedInput, $parameters));
             }
         }
         $parameters = $this->clearClasses($parameters);
         $parameters = $this->generateHumanReadableTypes($parameters);
         if ('PUT' === $annotation->getMethod()) {
             // All parameters are optional with PUT (update)
             array_walk($parameters, function ($val, $key) use(&$parameters) {
                 $parameters[$key]['required'] = false;
             });
         }
         $annotation->setParameters($parameters);
     }
     // output (populates 'response' for the formatters)
     if (null !== ($output = $annotation->getOutput())) {
         $response = array();
         $supportedParsers = array();
         if (strpos(strtolower($output), '.json')) {
             $path = 'file://' . realpath($this->schemaPath . $output);
             $properties = (array) json_decode(file_get_contents($path))->properties;
             foreach ($properties as $objectName => $property) {
                 if (isset($property->properties)) {
                     $response = array_merge($response, $annotation->schemaFormat($property->properties, $property->required, $objectName));
                 } else {
                     $required = json_decode(file_get_contents($path))->required;
                     $response = array_merge($response, $annotation->schemaFormat($properties, $required));
                 }
             }
             $annotation->setResponse($response);
             $annotation->setResponseForStatusCode($response, [], 200);
         } else {
             $normalizedOutput = $this->normalizeClassParameter($output);
             foreach ($this->getParsers($normalizedOutput) as $parser) {
                 if ($parser->supports($normalizedOutput)) {
                     $supportedParsers[] = $parser;
                     $response = $this->mergeParameters($response, $parser->parse($normalizedOutput));
                 }
             }
             foreach ($supportedParsers as $parser) {
                 if ($parser instanceof PostParserInterface) {
                     $mp = $parser->postParse($normalizedOutput, $response);
                     $response = $this->mergeParameters($response, $mp);
                 }
             }
             $response = $this->clearClasses($response);
             $response = $this->generateHumanReadableTypes($response);
             $annotation->setResponse($response);
             $annotation->setResponseForStatusCode($response, $normalizedOutput, 200);
         }
     }
     if (count($annotation->getResponseMap()) > 0 && !strpos(strtolower($annotation->getOutput()), '.json')) {
         foreach ($annotation->getResponseMap() as $code => $modelName) {
             if ('200' === (string) $code && isset($modelName['type']) && isset($modelName['model'])) {
                 /*
                  * Model was already parsed as the default `output` for this ApiDoc.
                  */
                 continue;
             }
             $normalizedModel = $this->normalizeClassParameter($modelName);
             $parameters = array();
             $supportedParsers = array();
             foreach ($this->getParsers($normalizedModel) as $parser) {
                 if ($parser->supports($normalizedModel)) {
                     $supportedParsers[] = $parser;
                     $parameters = $this->mergeParameters($parameters, $parser->parse($normalizedModel));
                 }
             }
             foreach ($supportedParsers as $parser) {
                 if ($parser instanceof PostParserInterface) {
                     $mp = $parser->postParse($normalizedModel, $parameters);
                     $parameters = $this->mergeParameters($parameters, $mp);
                 }
             }
             $parameters = $this->clearClasses($parameters);
             $parameters = $this->generateHumanReadableTypes($parameters);
             $annotation->setResponseForStatusCode($parameters, $normalizedModel, $code);
         }
     }
     return $annotation;
 }