/**
  * @param string $name
  * @param string $package
  * @param array  $values
  *
  * @return \google\protobuf\FileDescriptorProto
  */
 protected function createFileDescriptorProto($name, $package, array $values = [])
 {
     $descriptor = new FileDescriptorProto();
     $extensions = isset($values['extensions']) ? $values['extensions'] : [];
     $options = isset($values['options']) ? $values['options'] : null;
     $messages = isset($values['messages']) ? $values['messages'] : [];
     $services = isset($values['services']) ? $values['services'] : [];
     $enums = isset($values['enums']) ? $values['enums'] : [];
     $descriptor->setName($name);
     $descriptor->setPackage($package);
     foreach ($extensions as $number => $field) {
         if (is_array($field)) {
             $name = $field[0];
             $type = $field[1];
             $label = $field[2];
             $extendee = $field[3];
             $typeName = isset($field[4]) ? $field[4] : null;
             $field = $this->createFieldDescriptorProto($number, $name, $type, $label, $typeName);
             $field->setExtendee($extendee);
         }
         $descriptor->addExtension($field);
     }
     foreach ($messages as $item) {
         if (is_array($item)) {
             $name = $item['name'];
             $fields = isset($item['fields']) ? $item['fields'] : [];
             $values = isset($item['values']) ? $item['values'] : [];
             $item = $this->createDescriptorProto($name, $fields, $values);
         }
         $descriptor->addMessageType($item);
     }
     foreach ($enums as $item) {
         if (is_array($item)) {
             $name = $item['name'];
             $values = isset($item['values']) ? $item['values'] : [];
             $item = $this->createEnumDescriptorProto($name, $values);
         }
         $descriptor->addEnumType($item);
     }
     foreach ($services as $item) {
         if (is_array($item)) {
             $name = $item['name'];
             $values = isset($item['values']) ? $item['values'] : [];
             $item = $this->createServiceDescriptorProto($name, $values);
         }
         $descriptor->addService($item);
     }
     if ($options !== null) {
         $fileOptions = new FileOptions();
         $optionsExt = isset($options['extensions']) ? $options['extensions'] : [];
         if (isset($options['packed'])) {
             $fileOptions->setPacked($options['packed']);
         }
         foreach ($optionsExt as $ext) {
             $fileOptions->extensions()->put($ext[0], $ext[1]);
         }
         $descriptor->setOptions($fileOptions);
     }
     return $descriptor;
 }