@param \Protobuf\Compiler\Entity             $entity
@param \google\protobuf\FieldDescriptorProto $field

@return string[]
510182
protected function generateFieldReadStatement(Entity $entity, FieldDescriptorProto $field)
    {
        $generator = new ReadFieldStatementGenerator($this->context);

        $generator->setBreakMode(ReadFieldStatementGenerator::BREAK_MODE_RETURN);
        $generator->setTargetVar('$value');

        return $generator->generateFieldReadStatement($entity, $field);
    }
499841
protected function getEntityAttributeValue($entity, $field)
    {
        $functionName = 'get'.ucfirst($field);

        $fieldValue = call_user_func([$entity, $functionName]);

        return $fieldValue;
    }
534329
protected function getEntityNamesOfFieldDescriptors($filterFields)
    {
        $fields = [];

        // filter array for DoctrineFieldDescriptors
        foreach ($filterFields as $field) {
            // add joins of field
            $fields = array_merge($fields, $field->getJoins());

            if ($field instanceof DoctrineFieldDescriptor
                || $field instanceof DoctrineJoinDescriptor
            ) {
                $fields[] = $field;
            }
        }

        $fieldEntityNames = [];
        foreach ($fields as $key => $field) {
            // special treatment for join descriptors
            if ($field instanceof DoctrineJoinDescriptor) {
                $fieldEntityNames[] = $key;
            }
            $fieldEntityNames[] = $field->getEntityName();
        }

        // unify result
        return array_unique($fieldEntityNames);
    }
325838
private function getScalarField($field)
	{
		$dataField = array_merge($this->defaultField, [
			'property' => $field->getName(),
			'title' => $field->getTitle(),
			'type' => get_class($field),
			'validators' => $field->getValidators(),
			'modifiers' => [
				'save' => $field->getSaveDataModifiers(),
				'fetch' => $field->getFetchDataModifiers(),
			],
		]);

		if($field instanceof Main\Entity\ScalarField){
			$dataField['primary'] = $field->isPrimary();
			$dataField['unique'] = $field->isUnique();
			$dataField['autocomplete'] = $field->isAutocomplete();
			$dataField['require'] = $field->isRequired();
			$dataField['serialized'] = $field->isSerialized();
			if(method_exists($field, 'getValues')){
				$dataField['values'] = $field->getValues();
			}
		} elseif ($field instanceof Main\Entity\ReferenceField){
			$ref = $field->getReference();
			$ref = array_shift($ref);

			preg_match('/^ref\.([a-zA-Z]+)$/i', $ref, $matchRef);

			$refEntity = $field->getRefEntity();
			$refNameShow = $matchRef[1];
			if($refEntity->hasField('NAME')){
				$refNameShow = $refEntity->getField('NAME')->getName();
			} elseif ($refEntity->hasField('TITLE')){
				$refNameShow = $refEntity->getField('TITLE')->getName();
			}
			$dataField['property'] = $field->getName().'_REF_'.$refNameShow;
			$dataField['virtual'] = true;
			$dataField['reference'] = [
				'FROM' => $field->getName(),
				'TO' => $refNameShow,
			];
		}

		return $dataField;
	}
942668
protected function generateAddMethod(Entity $entity, FieldDescriptorProto $field)
    {
        $fieldName  = $field->getName();
        $fieldType  = $field->getType();
        $collClass  = $this->getCollectionClassName($field);
        $methodName = 'add' . $this->getClassifiedName($field);
        $typeHint   = ($fieldType !== Type::TYPE_BYTES())
            ? $this->getDoctype($field)
            : null;

        $lines[] = 'if ($this->' . $fieldName . ' === null) {';
        $lines[] = '    $this->' . $fieldName . ' = new ' . $collClass . '();';
        $lines[] = '}';
        $lines[] = null;
        $lines[] = ($fieldType !== Type::TYPE_BYTES())
            ? '$this->' . $fieldName . '->add($value);'
            : '$this->' . $fieldName . '->add(\Protobuf\Stream::wrap($value));';

        return MethodGenerator::fromArray([
            'name'       => $methodName,
            'body'       => implode(PHP_EOL, $lines),
            'parameters' => [
                [
                    'name'   => 'value',
                    'type'   => $typeHint
                ]
            ],
            'docblock'   => [
                'shortDescription' => "Add a new element to '$fieldName'",
                'tags'             => [
                    [
                        'name'        => 'param',
                        'description' => $this->getDoctype($field) . ' $value'
                    ]
                ]
            ]
        ]);
    }
646268
protected function generateFieldSizeStatement(Entity $entity, FieldDescriptorProto $field)
    {
        $generator = new SerializedSizeFieldStatementGenerator($this->context);
        $statement = $generator->generateFieldSizeStatement($entity, $field);

        return $statement;
    }
869734
protected function generateFields(Entity $entity)
    {
        $fields     = [];
        $descriptor = $entity->getDescriptor();
        $extensions = $descriptor->getExtensionList() ?: [];

        foreach ($extensions as $field) {
            $fields[] = $this->generateExtensionField($entity, $field);
        }

        return $fields;
    }
463695
protected function generateFieldBody(FieldDescriptorProto $field)
    {
        $lines     = [];
        $name      = $field->getName();
        $number    = $field->getNumber();
        $typeName  = $field->getTypeName();
        $extendee  = $field->getExtendee();
        $type      = $field->getType()->name();
        $label     = $field->getLabel()->name();
        $default   = $this->getDefaultFieldValue($field);
        $values    = [
            'number'    => var_export($number, true),
            'name'      => var_export($name, true),
            'type'      => '\google\protobuf\FieldDescriptorProto\Type::' . $type . '()',
            'label'     => '\google\protobuf\FieldDescriptorProto\Label::' . $label . '()',
        ];

        if ($extendee) {
            $values['extendee'] = var_export($extendee, true);
        }

        if ($typeName) {
            $values['type_name'] = var_export($typeName, true);
        }

        if ($field->hasDefaultValue()) {
            $values['default_value'] = $default;
        }

        $lines[] = '\google\protobuf\FieldDescriptorProto::fromArray([';
        $lines   = array_merge($lines, $this->generateArrayLines($values));
        $lines[] = ']),';

        return $lines;
    }
901533
public function getBlockVariables($field, $entity)
    {
        $defaults = parent::getBlockVariables($field, $entity);

        // Date_format should be any format supported by http://php.net/manual/en/function.date.php
        $date_format = $field->getOption('date_format', 'c');

        $date = $defaults['value'];

        if (!$date instanceof \DateTime) {
            $variables = [
                'value' => null,
                'datetime' => null,
            ];
        }
        else {
            $variables = [
                'value' => $date->format($date_format),
                'datetime' => $date->format(\DateTime::RFC3339),
            ];
        }

        return $variables + $defaults;
    }
498162
protected function generateExtensionField(Entity $entity, FieldDescriptorProto $field)
    {
        $name     = $field->getName();
        $number   = $field->getNumber();
        $docBlock = $this->getDocBlockType($field);
        $type     = $this->getFieldTypeName($field);
        $label    = $this->getFieldLabelName($field);
        $property = PropertyGenerator::fromArray([
            'static'       => true,
            'name'         => $name,
            'visibility'   => PropertyGenerator::VISIBILITY_PROTECTED,
            'docblock'     => [
                'shortDescription' => "Extension field : $name $label $type = $number",
                'tags'             => [
                    [
                        'name'        => 'var',
                        'description' => '\Protobuf\Extension',
                    ]
                ]
            ]
        ]);

        $property->getDocblock()->setWordWrap(false);

        return $property;
    }
188235
protected function generateFieldWriteStatement(Entity $entity, FieldDescriptorProto $field)
    {
        $generator = new WriteFieldStatementGenerator($this->context);
        $statement = $generator->generateFieldWriteStatement($entity, $field);

        return $statement;
    }
1035468
protected function generateBody(Entity $entity)
    {
        $lines      = [];
        $fields     = [];
        $extensions = [];
        $descriptor = $entity->getDescriptor();

        if ($descriptor->hasOptions()) {
            $lines   = $this->createOptionsBody($entity);
            $lines[] = null;
        }

        foreach (($descriptor->getFieldList() ?: []) as $field) {
            $values = $this->generateFieldBody($field);
            $fields = array_merge($fields, $this->addIndentation($values, 2));
        }

        foreach (($descriptor->getExtensionList() ?: []) as $field) {
            $values     = $this->generateFieldBody($field);
            $extensions = array_merge($extensions, $this->addIndentation($values, 2));
        }

        $lines[] = "return \google\protobuf\DescriptorProto::fromArray([";
        $lines[] = "    'name'      => " . var_export($descriptor->getName(), true) . ",";

        if ( ! empty($fields)) {
            $lines[] = "    'field'     => [";
            $lines   = array_merge($lines, $fields);
            $lines[] = "    ],";
        }

        if ( ! empty($extensions)) {
            $lines[] = "    'extension' => [";
            $lines   = array_merge($lines, $extensions);
            $lines[] = "    ],";
        }

        if ($descriptor->hasOptions()) {
            $lines[] = "    'options' => \$options";
        }

        $lines[] = "]);";

        return $lines;
    }
1140216
protected function getExistingFields($entity)
    {
        /** @var FieldValueRepository $repo */
        $repo = $this->em->getRepository(Entity\FieldValue::class);

        return $repo->getExistingFields($entity->getId(), $entity->getContenttype(), $this->mapping['fieldname']);
    }
1320226
protected function generateBody(Entity $entity)
    {
        $descriptor = $entity->getDescriptor();
        $fields     = $descriptor->getFieldList() ?: [];

        $body[] = '$stream      = $context->getStream();';
        $body[] = '$writer      = $context->getWriter();';
        $body[] = '$sizeContext = $context->getComputeSizeContext();';
        $body[] = null;

        foreach ($fields as $field) {
            $lines = $this->generateRequiredFieldException($entity, $field);
            $body  = array_merge($body, $lines);
        }

        foreach ($fields as $field) {
            $lines = $this->generateFieldCondition($entity, $field);
            $body  = array_merge($body, $lines, [null]);
        }

        $extensionsField = $this->getUniqueFieldName($descriptor, 'extensions');
        $extensionsVar   = '$this->' . $extensionsField;

        $body[] = 'if (' . $extensionsVar . ' !== null) {';
        $body[] = '    ' . $extensionsVar . '->writeTo($context);';
        $body[] = '}';
        $body[] = null;
        $body[] = 'return $stream;';

        return $body;
    }
512597
public function error($field)
    {
        $parts = explode('.', $field);
        $entity = $this->entity($parts);

        if ($entity instanceof EntityInterface) {
            return $entity->getError(array_pop($parts));
        }

        return [];
    }
756677
protected function generateWriteCallback(Entity $entity, FieldDescriptorProto $field)
    {
        $body  = [];
        $sttm  = $this->generateFieldWriteStatement($entity, $field);
        $lines = $this->addIndentation($sttm, 1);

        $body[] = '$writeCallback = function (\Protobuf\WriteContext $context, $value) {';
        $body[] = '    $stream      = $context->getStream();';
        $body[] = '    $writer      = $context->getWriter();';
        $body[] = '    $sizeContext = $context->getComputeSizeContext();';
        $body[] = null;
        $body   = array_merge($body, $lines);
        $body[] = '};';

        return $body;
    }
689414
public function getErrorsForField(EntityDescriptor $ed, $field) {
		$r = array();
		foreach( static::$testedValues as $value ) {
			try {
				$ed->validateFieldValue($field, $value);
			} catch( InvalidFieldException $e ) {
				$r[$e->getKey()] = $e;
			}
		}
		return $r;
	}