<?php require_once 'TlDocumentationGenerator.php'; class JavadocTlDocumentationGenerator extends TlDocumentationGenerator { private $nullable_type; private $nullable_annotation; private $java_version; protected function escapeDocumentation($doc) { $doc = preg_replace_callback('/(?<!["A-Za-z_\/])[A-Za-z]*_[A-Za-z_]*/', function ($word_matches) { return preg_replace_callback('/_([A-Za-z])/', function ($matches) {return strtoupper($matches[1]);}, $word_matches[0]); }, $doc); $doc = htmlspecialchars($doc, ENT_COMPAT, 'UTF-8'); $doc = str_replace('*/', '*/', $doc); return $doc; } protected function getFieldName($name, $class_name) { if (substr($name, 0, 6) === 'param_') { $name = substr($name, 6); } return preg_replace_callback('/_([A-Za-z])/', function ($matches) {return strtoupper($matches[1]);}, trim($name)); } protected function getClassName($type) { return implode(array_map('ucfirst', explode('.', trim($type, "\r\n ;")))); } protected function getTypeName($type) { switch ($type) { case 'Bool': return 'boolean'; case 'int32': return 'int'; case 'int53': case 'int64': return 'long'; case 'double': return $type; case 'string': return 'String'; case 'bytes': return 'byte[]'; case 'bool': case 'int': case 'long': case 'Int': case 'Long': case 'Int32': case 'Int53': case 'Int64': case 'Double': case 'String': case 'Bytes': $this->printError("Wrong type $type"); return ''; default: if (substr($type, 0, 6) === 'vector') { if ($type[6] !== '<' || $type[strlen($type) - 1] !== '>') { $this->printError("Wrong vector subtype in $type"); return ''; } return $this->getTypeName(substr($type, 7, -1)).'[]'; } if (preg_match('/[^A-Za-z0-9.]/', $type)) { $this->printError("Wrong type $type"); return ''; } return $this->getClassName($type); } } protected function getBaseClassName($is_function) { return $is_function ? 'Function' : 'Object'; } protected function needRemoveLine($line) { return strpos(trim($line), '/**') === 0 || strpos(trim($line), '*') === 0 || ($this->nullable_type && strpos($line, $this->nullable_type) > 0); } protected function needSkipLine($line) { $line = $this->fixLine(trim($line)); return (strpos($line, 'public') !== 0 && !$this->isHeaderLine($line)) || $line === 'public @interface Constructors {}'; } protected function isHeaderLine($line) { return trim($line) === '@Override' || trim($line) === '@Constructors'; } protected function extractClassName($line) { if (strpos($line, 'public static class ') > 0) { return preg_split('/( |<|>)/', trim($line))[3]; } return ''; } protected function fixLine($line) { if (strpos($line, 'CONSTRUCTOR = ') > 0) { return substr($line, 0, strpos($line, '=')); } return $this->nullable_annotation ? str_replace($this->nullable_annotation.' ', '', $line) : $line; } protected function addGlobalDocumentation() { if ($this->nullable_type) { $nullable_type_import = "import $this->nullable_type;".PHP_EOL; } else { $nullable_type_import = ''; } $this->addDocumentation('public class TdApi {', <<<EOT $nullable_type_import/** * This class contains as static nested classes all other TDLib interface * type-classes and function-classes. * <p> * It has no inner classes, functions or public members. */ EOT ); $this->addDocumentation(' public abstract static class Object {', <<<EOT /** * This class is a base class for all TDLib interface classes. */ EOT ); $this->addDocumentation(" public Object() {", <<<EOT /** * Default Object constructor. */ EOT ); $this->addDocumentation(' public abstract int getConstructor();', <<<EOT /** * Returns an identifier uniquely determining type of the object. * * @return a unique identifier of the object type. */ EOT ); $this->addDocumentation(' public native String toString();', <<<EOT /** * Returns a string representation of the object. * * @return a string representation of the object. */ EOT ); $this->addDocumentation(' public abstract static class Function<R extends Object> extends Object {', <<<EOT /** * This class is a base class for all TDLib interface function-classes. * * @param <R> The object type that is returned by the function */ EOT ); $this->addDocumentation(" public Function() {", <<<EOT /** * Default Function constructor. */ EOT ); $this->addDocumentation(' public static final int CONSTRUCTOR', <<<EOT /** * Identifier uniquely determining type of the object. */ EOT ); $this->addDocumentation(' public int getConstructor() {', <<<EOT /** * @return this.CONSTRUCTOR */ EOT ); } protected function addAbstractClassDocumentation($class_name, $documentation) { $this->addDocumentation(" public abstract static class $class_name extends Object {", <<<EOT /** * This class is an abstract base class. * $documentation */ EOT ); $this->addDocumentation(" public $class_name() {", <<<EOT /** * Default class constructor. */ EOT ); } protected function getFunctionReturnTypeDescription($return_type, $for_constructor) { $shift = $for_constructor ? ' ' : ' '; return PHP_EOL.$shift.'*'.PHP_EOL.$shift."* <p> Returns {@link $return_type $return_type} </p>"; } protected function addClassDocumentation($class_name, $base_class_name, $return_type, $description) { $this->addDocumentation(" public static class $class_name extends ".$base_class_name.(empty($return_type) ? "" : "<".$return_type.">")." {", <<<EOT /** * $description */ EOT ); } protected function addFieldDocumentation($class_name, $field_name, $type_name, $field_info, $may_be_null) { $full_line = $class_name." public $type_name $field_name;"; $this->addDocumentation($full_line, <<<EOT /** * $field_info */ EOT ); if ($may_be_null && $this->nullable_annotation && ($this->java_version >= 8 || substr($type_name, -1) != ']')) { $this->addLineReplacement($full_line, " $this->nullable_annotation public $type_name $field_name;".PHP_EOL); } } protected function addDefaultConstructorDocumentation($class_name, $class_description) { $this->addDocumentation(" public $class_name() {", <<<EOT /** * $class_description */ EOT ); } protected function addFullConstructorDocumentation($class_name, $class_description, $known_fields, $info) { $full_constructor = " public $class_name("; $colon = ''; foreach ($known_fields as $name => $type) { $full_constructor .= $colon.$this->getTypeName($type).' '.$this->getFieldName($name, $class_name); $colon = ', '; } $full_constructor .= ') {'; $full_doc = <<<EOT /** * $class_description * EOT; foreach ($known_fields as $name => $type) { $full_doc .= ' * @param '.$this->getFieldName($name, $class_name).' '.$info[$name].PHP_EOL; } $full_doc .= ' */'; $this->addDocumentation($full_constructor, $full_doc); } public function __construct($nullable_type, $nullable_annotation, $java_version) { $this->nullable_type = trim($nullable_type); $this->nullable_annotation = trim($nullable_annotation); $this->java_version = intval($java_version); } } $nullable_type = isset($argv[3]) ? $argv[3] : ''; $nullable_annotation = isset($argv[4]) ? $argv[4] : ''; $java_version = isset($argv[5]) ? intval($argv[5]) : 7; $generator = new JavadocTlDocumentationGenerator($nullable_type, $nullable_annotation, $java_version); $generator->generate($argv[1], $argv[2]);