@param \google\protobuf\FieldDescriptorProto $field

@return string
505758
protected function getCollectionClassName(FieldDescriptorProto $field)
    {
        $type = $field->getType();

        if ($type === Type::TYPE_MESSAGE()) {
            return '\Protobuf\MessageCollection';
        }

        if ($type === Type::TYPE_BYTES()) {
            return '\Protobuf\StreamCollection';
        }

        if ($type === Type::TYPE_ENUM()) {
            return '\Protobuf\EnumCollection';
        }

        return '\Protobuf\ScalarCollection';
    }
486851
public function get_field_raw( $field ) {
		if ( array_key_exists( $field, $this->prop( 'fields' ) ) ) {
			return $this->prop( 'fields' )[ $field ];
		}

		return null;
	}
847705
private function buildPrefix(Field $field)
    {
        $prefix = $field->get('prefix');

        if (! is_null($prefix)) {
            foreach (array_filter(explode(' ', $prefix)) as $name) {
                $prefix .= '['.$name.']';
            }

            return $prefix;
        }

        return $this->prefix;
    }
393883
public static function snakeCaseToCamelCase(string $field): string
    {
        return lcfirst(str_replace(
            self::DELIMITER_UNDERSCORE,
            self::STRING_EMPTY,
            ucwords($field, self::DELIMITER_UNDERSCORE)
        ));
    }
1000371
protected function generateGetterMethod(Entity $entity, FieldDescriptorProto $field)
    {
        $fieldName  = $field->getName();
        $methodName = $this->getAccessorName('get', $field);
        $method     = MethodGenerator::fromArray([
            'name'       => $methodName,
            'body'       => 'return $this->' . $fieldName . ';',
            'docblock'   => [
                'shortDescription' => "Get '$fieldName' value",
                'tags'             => [
                    [
                        'name'        => 'return',
                        'description' => $this->getDocBlockType($field),
                    ]
                ]
            ]
        ]);

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

        return $method;
    }
1349794
protected function formatField(Field $field)
    {
        $jsonKey = $field->column();

        $elementName = $elementClass = $errorKey = [];

        if (is_array($jsonKey)) {
            foreach ($jsonKey as $index => $name) {
                $elementName[$index] = "{$this->column}[$name]";
                $errorKey[$index] = "{$this->column}.$name";
                $elementClass[$index] = "{$this->column}_$name";
            }
        } else {
            $elementName = "{$this->column}[$jsonKey]";
            $errorKey = "{$this->column}.$jsonKey";
            $elementClass = "{$this->column}_$jsonKey";
        }

        $field->setElementName($elementName)
            ->setErrorKey($errorKey)
            ->setElementClass($elementClass);

        return $field;
    }
607811
public function getFieldInfo($field)
    {
        $name = $field->getName();
        $type = '';
        if ($field instanceof IntegerField || $field instanceof AutoField) {
            $type = 'int';
        }
        if ($field instanceof CharField) {
            $type = 'string';
        }

        if ($field instanceof FloatField || $field instanceof DecimalField) {
            $type = 'float';
        }

        if ($field instanceof DateField) {
            $type = '\\'.\DateTime::class;
        }

        if ($field instanceof RelatedField) {
            $field->setNull(true);
            /** @var $desc RelationDescriptor* */
            $desc = $field->getDescriptor();
            $manger = $desc->getManagerClass();
            $type = '\\'.$manger;
        }
        if ($field instanceof ForeignObjectRel) {
            $name = $field->getAccessorName();

            /** @var $desc RelationDescriptor* */
            $desc = $this->model->{$name};
            $manger = $desc->getManagerClass();
            $type = '\\'.$manger;
        }

        return [$type, $name];
    }
855824
protected function getMethodInputTypeHint(MethodDescriptorProto $method)
    {
        $refType   = $method->getInputType();
        $refEntity = $this->getEntity($refType);

        if ($method->getClientStreaming()) {
            return '\Iterator';
        }

        return $refEntity->getNamespacedName();
    }
152222
public function addField(\google\protobuf\FieldDescriptorProto $value)
    {
        if ($this->field === null) {
            $this->field = new \Protobuf\MessageCollection();
        }

        $this->field->add($value);
    }
1309929
protected function getUniqueFieldName(DescriptorProto $descriptor, $default)
    {
        $extensions = $descriptor->getExtensionList() ?: [];
        $fields     = $descriptor->getFieldList() ?: [];
        $name       = $default;
        $names      = [];
        $count      = 0;

        foreach ($fields as $field) {
            $names[$field->getName()] = true;
        }

        foreach ($extensions as $field) {
            $names[$field->getName()] = true;
        }

        while (isset($names[$name])) {
            $name = $default . ($count ++);
        }

        return $name;
    }
756705
protected function generateAddValue(Entity $entity, FieldDescriptorProto $field)
    {
        $lines      = [];
        $fieldName  = $field->getName();
        $methodName = 'add' . $this->getClassifiedName($field);

        $lines[] = 'foreach ($values[\'' . $fieldName . '\'] as $item) {';
        $lines[] = '    $message->' . $methodName . '($item);';
        $lines[] = '}';

        return $lines;
    }
964382
public static function camelCaseToSnakeCase(string $field): string
    {
        return strtolower(preg_replace(self::REGEX_CAPITAL, self::REPLACEMENT_UNDERSCORE, $field));
    }
941575
public static function getFieldDescriptor($proto)
    {
        $type_name = null;
        $type = $proto->getType();
        switch ($type) {
            case GPBType::MESSAGE:
            case GPBType::GROUP:
            case GPBType::ENUM:
                $type_name = $proto->getTypeName();
                break;
            default:
                break;
        }

        $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1;
        $packed = false;
        $options = $proto->getOptions();
        if ($options !== null) {
            $packed = $options->getPacked();
        }

        $field = new FieldDescriptor();
        $field->setName($proto->getName());

        $json_name = $proto->hasJsonName() ? $proto->getJsonName() :
            lcfirst(implode('', array_map('ucwords', explode('_', $proto->getName()))));
        if ($proto->hasJsonName()) {
            $json_name = $proto->getJsonName();
        } else {
            $proto_name = $proto->getName();
            $json_name = implode('', array_map('ucwords', explode('_', $proto_name)));
            if ($proto_name[0] !== "_" && !ctype_upper($proto_name[0])) {
                $json_name = lcfirst($json_name);
            }
        }
        $field->setJsonName($json_name);

        $camel_name = implode('', array_map('ucwords', explode('_', $proto->getName())));
        $field->setGetter('get' . $camel_name);
        $field->setSetter('set' . $camel_name);
        $field->setType($proto->getType());
        $field->setNumber($proto->getNumber());
        $field->setLabel($proto->getLabel());
        $field->setPacked($packed);
        $field->setTypeName($proto->getTypeName());
        $field->setOneofIndex($oneof_index);

        // At this time, the message/enum type may have not been added to pool.
        // So we use the type name as place holder and will replace it with the
        // actual descriptor in cross building.
        switch ($type) {
            case GPBType::MESSAGE:
                $field->setMessageType($type_name);
                break;
            case GPBType::ENUM:
                $field->setEnumType($type_name);
                break;
            default:
                break;
        }

        return $field;
    }
628636
public function getFieldType($field)
    {
        $definition = $this->getFieldDefinition($field);
        if ($definition && isset($definition['type'])) {
            return $definition['type'];
        }
    }
672139
protected function getMethodInputDocblock(MethodDescriptorProto $method)
    {
        $refType   = $method->getInputType();
        $refEntity = $this->getEntity($refType);
        $refClass  = $this->getMethodInputTypeHint($method);

        if ($method->getClientStreaming()) {
            return sprintf('\Iterator<%s>', $refEntity->getNamespacedName());
        }

        return $refClass;
    }
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'
                    ]
                ]
            ]
        ]);
    }
608555
protected function generateFieldMerge(Entity $entity, FieldDescriptorProto $field)
    {
        $lines     = [];
        $fieldName = $field->getName();
        $format    = '$this->%s = ($message->%s !== null) ? $message->%s : $this->%s;';
        $lines[]   = sprintf($format, $fieldName, $fieldName, $fieldName, $fieldName);

        return $lines;
    }