• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 gRPC authors.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# the spaces in the parameter list are necessary to separate out local variables
16function sed_gensub(regexp, replacement, how, target,         cmd_, ret_) { # arguments and local variables
17    if (!target) {
18        target = $0
19    }
20    gsub(/'/, "'\"'\"'", target);
21    gsub(/\\\\/, "\\", regexp);
22
23    cmd_ = "printf '" target "' | sed -nE 's/" regexp "/" replacement "/" tolower(how) "p'";
24    if (cmd_ | getline ret_ != 1) {
25        close(cmd_);
26        error = "ERROR: running command: " cmd_ ", ret_: " ret_;
27        exit;
28    }
29    close(cmd_);
30    return ret_;
31}
32
33BEGIN {
34    namespace = "Grpc";
35    className = "";
36    classDocComment = "";
37
38    delete methodNames; # i => methodName
39    delete methodArgs; # methodName => concatenatedArgsStr
40    delete methodDocs; # methodName => methodDocCommentStr
41    delete methodStatics; # methodName => 1 if static
42    methodsCount = 0;
43
44    delete constantNames; # i => constantName
45    delete constantDocs; # constantName => constantDocCommentStr
46    constantsCount = 0;
47
48    #  * class className
49    classLineRegex = "^ \\* class ([^ \t]+)$";
50    # @param type name [= default]
51    paramLineRegex = "^.*@param[ \t]+[^ \t]+[ \t]+(\\$[^ \t]+([ \t]+=[ \t]+[^ \t]+)?)[ \t]+.*$";
52    # PHP_METHOD(class, function)
53    phpMethodLineRegex = "^PHP_METHOD\\(([^ \t]+),[ \t]*([^ \t]+)\\).*$";
54
55    # PHP_ME(class, function, arginfo, flags)
56    phpMeLineRegex = "^[ \t]*PHP_ME\\(([^ \t]+),[ \t]*([^ \t]+),.*$";
57
58    # REGISTER_LONG_CONSTANT("namespace\\constant", grpcConstant, ..)
59    phpConstantLineRegs = "^[ \t]*REGISTER_LONG_CONSTANT\\(\"Grpc\\\\\\\\([^ \t]+)\",.*$";
60
61    error = "";
62
63    # extension testing methods
64    hideMethods["Channel::getChannelInfo"] = 1;
65    hideMethods["Channel::cleanPersistentList"] = 1;
66    hideMethods["Channel::getPersistentList"] = 1;
67}
68
69# '/**' document comment start
70/^[ \t]*\/\*\*/ {
71    inDocComment = 1;
72    docComment = "";
73    delete args;
74    argsCount = 0;
75}
76
77# collect document comment
78inDocComment==1 {
79    docComment = docComment"\n"$0
80}
81
82# class document, must match ' * class <clasName>'
83inDocComment==1 && $0 ~ classLineRegex {
84    className = sed_gensub(classLineRegex, "\\1", "g");
85}
86
87# end of class document
88inDocComment==1 && /\*\// && className && classDocComment == "" {
89    classDocComment = docComment;
90    docComment = "";
91}
92
93# param line
94inDocComment==1 && $0 ~ paramLineRegex {
95    arg = sed_gensub(paramLineRegex, "\\1", "g");
96    args[argsCount++]=arg;
97}
98
99# '*/' document comment end
100inDocComment==1 && /\*\// {
101    inDocComment = 0;
102}
103
104# PHP_METHOD
105$0 ~ phpMethodLineRegex {
106    class = sed_gensub(phpMethodLineRegex, "\\1", "g");
107    if (class != className) {
108        error = "ERROR: Missing or mismatch class names, in class comment block: " \
109          className ", in PHP_METHOD: " class;
110        exit;
111    };
112
113    method = sed_gensub(phpMethodLineRegex, "\\2", "g");
114    methodNames[methodsCount++] = method;
115    methodDocs[method] = docComment;
116
117    # concat args
118    if (argsCount > 0) {
119        methodArgs[method] = args[0];
120        for (i = 1; i < argsCount; i++) {
121            methodArgs[method] = methodArgs[method] ", " args[i];
122        }
123    }
124
125    docComment = "";
126}
127
128# PHP_ME(class, function,...
129$0 ~ phpMeLineRegex {
130    inPhpMe = 1;
131
132    class = sed_gensub(phpMeLineRegex, "\\1", "g");
133    if (class != className) {
134        error = "ERROR: Missing or mismatch class names, in class comment block: " \
135          className ", in PHP_ME: " class;
136        exit;
137    };
138    method = sed_gensub(phpMeLineRegex, "\\2", "g");
139}
140
141# ZEND_ACC_STATIC
142inPhpMe && /ZEND_ACC_STATIC/ {
143    methodStatics[method] = 1;
144}
145
146# closing bracet of PHP_ME(...)
147iinPhpMe && /\)$/ {
148    inPhpMe = 0;
149}
150
151# REGISTER_LONG_CONSTANT(constant, ...
152$0 ~ phpConstantLineRegs {
153    inPhpConstant = 1;
154    constant = sed_gensub(phpConstantLineRegs, "\\1", "g");
155    constantNames[constantsCount++] = constant;
156    constantDocs[constant] = docComment;
157}
158
159# closing bracet of REGISTER_LONG_CONSTANT(...)
160inPhpConstant && /\)[ \t]*;[ \t]*$/ {
161    inPhpConstant = 0;
162    docComment = "";
163}
164
165END {
166    if (error) {
167        print error > "/dev/stderr";
168        exit 1;
169    }
170
171    print "<?php\n"
172    print "namespace " namespace "{";
173
174    if (className != "") {
175        print classDocComment
176        print "class " className " {";
177        for (i = 0; i < methodsCount; i++) {
178            m = methodNames[i];
179            if (hideMethods[className"::"m]) continue;
180
181            print methodDocs[m];
182            printf "public"
183            if (methodStatics[m]) printf " static"
184            printf " function " m "("
185            printf methodArgs[m];
186            print ") {}";
187        }
188        print "\n}";
189    }
190
191    for (i = 0; i < constantsCount; i++) {
192        print constantDocs[constantNames[i]];
193        print "const " constantNames[i] " = 0;";
194    }
195
196    print "\n}";
197}
198