23
23
import javax .lang .model .type .TypeMirror ;
24
24
import javax .lang .model .util .Elements ;
25
25
26
- import static org .elasticsearch .compute .gen .Methods .appendMethod ;
27
26
import static org .elasticsearch .compute .gen .Methods .buildFromFactory ;
28
27
import static org .elasticsearch .compute .gen .Methods .getMethod ;
29
28
import static org .elasticsearch .compute .gen .Types .ABSTRACT_CONVERT_FUNCTION_EVALUATOR ;
41
40
public class ConvertEvaluatorImplementer {
42
41
43
42
private final TypeElement declarationType ;
44
- private final ExecutableElement processFunction ;
43
+ private final EvaluatorImplementer . ProcessFunction processFunction ;
45
44
private final String extraName ;
46
45
private final ClassName implementation ;
47
46
private final TypeName argumentType ;
48
- private final TypeName resultType ;
49
47
private final List <TypeMirror > warnExceptions ;
50
48
51
49
public ConvertEvaluatorImplementer (
52
50
Elements elements ,
51
+ javax .lang .model .util .Types types ,
53
52
ExecutableElement processFunction ,
54
53
String extraName ,
55
54
List <TypeMirror > warnExceptions
56
55
) {
57
56
this .declarationType = (TypeElement ) processFunction .getEnclosingElement ();
58
- this .processFunction = processFunction ;
59
- if (processFunction .getParameters ().size () != 1 ) {
60
- throw new IllegalArgumentException ("processing function should have exactly one parameter" );
57
+ this .processFunction = new EvaluatorImplementer .ProcessFunction (types , processFunction , warnExceptions );
58
+
59
+ if (this .processFunction .args .getFirst () instanceof EvaluatorImplementer .StandardProcessFunctionArg == false ) {
60
+ throw new IllegalArgumentException ("first argument must be the field to process" );
61
+ }
62
+ for (int a = 1 ; a < this .processFunction .args .size (); a ++) {
63
+ if (this .processFunction .args .get (a ) instanceof EvaluatorImplementer .FixedProcessFunctionArg == false ) {
64
+ throw new IllegalArgumentException ("fixed function args supported after the first" );
65
+ // TODO support more function types when we need them
66
+ }
61
67
}
68
+
62
69
this .extraName = extraName ;
63
70
this .argumentType = TypeName .get (processFunction .getParameters ().get (0 ).asType ());
64
- this .resultType = TypeName .get (processFunction .getReturnType ());
65
71
this .warnExceptions = warnExceptions ;
66
72
67
73
this .implementation = ClassName .get (
@@ -87,29 +93,36 @@ private TypeSpec type() {
87
93
builder .addModifiers (Modifier .PUBLIC , Modifier .FINAL );
88
94
builder .superclass (ABSTRACT_CONVERT_FUNCTION_EVALUATOR );
89
95
96
+ for (EvaluatorImplementer .ProcessFunctionArg a : processFunction .args ) {
97
+ a .declareField (builder );
98
+ }
90
99
builder .addMethod (ctor ());
91
- builder .addMethod (name ());
100
+ builder .addMethod (next ());
92
101
builder .addMethod (evalVector ());
93
102
builder .addMethod (evalValue (true ));
94
103
builder .addMethod (evalBlock ());
95
104
builder .addMethod (evalValue (false ));
105
+ builder .addMethod (processFunction .toStringMethod (implementation ));
106
+ builder .addMethod (processFunction .close ());
96
107
builder .addType (factory ());
97
108
return builder .build ();
98
109
}
99
110
100
111
private MethodSpec ctor () {
101
112
MethodSpec .Builder builder = MethodSpec .constructorBuilder ().addModifiers (Modifier .PUBLIC );
102
- builder .addParameter (EXPRESSION_EVALUATOR , "field" );
103
113
builder .addParameter (SOURCE , "source" );
114
+ builder .addStatement ("super(driverContext, source)" );
115
+ for (EvaluatorImplementer .ProcessFunctionArg a : processFunction .args ) {
116
+ a .implementCtor (builder );
117
+ }
104
118
builder .addParameter (DRIVER_CONTEXT , "driverContext" );
105
- builder .addStatement ("super(driverContext, field, source)" );
106
119
return builder .build ();
107
120
}
108
121
109
- private MethodSpec name () {
110
- MethodSpec .Builder builder = MethodSpec .methodBuilder ("name" ).addModifiers (Modifier .PUBLIC );
111
- builder .addAnnotation ( Override . class ). returns (String . class );
112
- builder .addStatement ("return $S " , declarationType . getSimpleName () + extraName );
122
+ private MethodSpec next () {
123
+ MethodSpec .Builder builder = MethodSpec .methodBuilder ("next" ). addAnnotation ( Override . class ).addModifiers (Modifier .PUBLIC );
124
+ builder .returns (EXPRESSION_EVALUATOR );
125
+ builder .addStatement ("return $N " , (( EvaluatorImplementer . StandardProcessFunctionArg ) processFunction . args . getFirst ()). name () );
113
126
return builder .build ();
114
127
}
115
128
@@ -129,7 +142,7 @@ private MethodSpec evalVector() {
129
142
builder .beginControlFlow ("if (vector.isConstant())" );
130
143
{
131
144
catchingWarnExceptions (builder , () -> {
132
- var constVectType = blockType ( resultType );
145
+ var constVectType = processFunction . resultDataType ( true );
133
146
builder .addStatement (
134
147
"return driverContext.blockFactory().newConstant$TWith($N, positionCount)" ,
135
148
constVectType ,
@@ -139,7 +152,7 @@ private MethodSpec evalVector() {
139
152
}
140
153
builder .endControlFlow ();
141
154
142
- ClassName resultBuilderType = builderType (blockType ( resultType ));
155
+ ClassName resultBuilderType = builderType (processFunction . resultDataType ( true ));
143
156
builder .beginControlFlow (
144
157
"try ($T builder = driverContext.blockFactory().$L(positionCount))" ,
145
158
resultBuilderType ,
@@ -150,7 +163,11 @@ private MethodSpec evalVector() {
150
163
{
151
164
catchingWarnExceptions (
152
165
builder ,
153
- () -> builder .addStatement ("builder.$L($N)" , appendMethod (resultType ), evalValueCall ("vector" , "p" , scratchPadName )),
166
+ () -> builder .addStatement (
167
+ "builder.$L($N)" ,
168
+ processFunction .appendMethod (),
169
+ evalValueCall ("vector" , "p" , scratchPadName )
170
+ ),
154
171
() -> builder .addStatement ("builder.appendNull()" )
155
172
);
156
173
}
@@ -185,7 +202,7 @@ private MethodSpec evalBlock() {
185
202
TypeName blockType = blockType (argumentType );
186
203
builder .addStatement ("$T block = ($T) b" , blockType , blockType );
187
204
builder .addStatement ("int positionCount = block.getPositionCount()" );
188
- TypeName resultBuilderType = builderType (blockType ( resultType ));
205
+ TypeName resultBuilderType = builderType (processFunction . resultDataType ( true ));
189
206
builder .beginControlFlow (
190
207
"try ($T builder = driverContext.blockFactory().$L(positionCount))" ,
191
208
resultBuilderType ,
@@ -196,19 +213,18 @@ private MethodSpec evalBlock() {
196
213
builder .addStatement ("BytesRef $N = new BytesRef()" , scratchPadName );
197
214
}
198
215
199
- String appendMethod = appendMethod (resultType );
216
+ String appendMethod = processFunction . appendMethod ();
200
217
builder .beginControlFlow ("for (int p = 0; p < positionCount; p++)" );
201
218
{
202
219
builder .addStatement ("int valueCount = block.getValueCount(p)" );
203
220
builder .addStatement ("int start = block.getFirstValueIndex(p)" );
204
221
builder .addStatement ("int end = start + valueCount" );
205
222
builder .addStatement ("boolean positionOpened = false" );
206
223
builder .addStatement ("boolean valuesAppended = false" );
207
- // builder.addStatement("builder.beginPositionEntry()");
208
224
builder .beginControlFlow ("for (int i = start; i < end; i++)" );
209
225
{
210
226
catchingWarnExceptions (builder , () -> {
211
- builder .addStatement ("$T value = $N" , resultType , evalValueCall ("block" , "i" , scratchPadName ));
227
+ builder .addStatement ("$T value = $N" , processFunction . returnType () , evalValueCall ("block" , "i" , scratchPadName ));
212
228
builder .beginControlFlow ("if (positionOpened == false && valueCount > 1)" );
213
229
{
214
230
builder .addStatement ("builder.beginPositionEntry()" );
@@ -253,8 +269,8 @@ private String evalValueCall(String container, String index, String scratchPad)
253
269
254
270
private MethodSpec evalValue (boolean forVector ) {
255
271
MethodSpec .Builder builder = MethodSpec .methodBuilder ("evalValue" )
256
- .addModifiers (Modifier .PRIVATE , Modifier . STATIC )
257
- .returns (resultType );
272
+ .addModifiers (Modifier .PRIVATE )
273
+ .returns (processFunction . returnType () );
258
274
259
275
if (forVector ) {
260
276
builder .addParameter (vectorType (argumentType ), "container" );
@@ -269,8 +285,17 @@ private MethodSpec evalValue(boolean forVector) {
269
285
builder .addStatement ("$T value = container.$N(index)" , argumentType , getMethod (argumentType ));
270
286
}
271
287
272
- builder .addStatement ("return $T.$N(value)" , declarationType , processFunction .getSimpleName ());
273
-
288
+ StringBuilder pattern = new StringBuilder ();
289
+ List <Object > args = new ArrayList <>();
290
+ pattern .append ("return $T.$N(value" );
291
+ args .add (declarationType );
292
+ args .add (processFunction .function .getSimpleName ());
293
+ for (int a = 1 ; a < processFunction .args .size (); a ++) {
294
+ pattern .append (", " );
295
+ processFunction .args .get (a ).buildInvocation (pattern , args , false /* block style parameter should be unused */ );
296
+ }
297
+ pattern .append (")" );
298
+ builder .addStatement (pattern .toString (), args .toArray ());
274
299
return builder .build ();
275
300
}
276
301
@@ -280,42 +305,11 @@ private TypeSpec factory() {
280
305
builder .addModifiers (Modifier .PUBLIC , Modifier .STATIC );
281
306
282
307
builder .addField (SOURCE , "source" , Modifier .PRIVATE , Modifier .FINAL );
283
- builder .addField (EXPRESSION_EVALUATOR_FACTORY , "field" , Modifier .PRIVATE , Modifier .FINAL );
284
-
285
- builder .addMethod (factoryCtor ());
286
- builder .addMethod (factoryGet ());
287
- builder .addMethod (factoryToString ());
288
- return builder .build ();
289
- }
290
-
291
- private MethodSpec factoryCtor () {
292
- MethodSpec .Builder builder = MethodSpec .constructorBuilder ().addModifiers (Modifier .PUBLIC );
293
- builder .addParameter (EXPRESSION_EVALUATOR_FACTORY , "field" );
294
- builder .addParameter (SOURCE , "source" );
295
- builder .addStatement ("this.field = field" );
296
- builder .addStatement ("this.source = source" );
297
- return builder .build ();
298
- }
299
-
300
- private MethodSpec factoryGet () {
301
- MethodSpec .Builder builder = MethodSpec .methodBuilder ("get" ).addAnnotation (Override .class );
302
- builder .addModifiers (Modifier .PUBLIC );
303
- builder .addParameter (DRIVER_CONTEXT , "context" );
304
- builder .returns (implementation );
305
-
306
- List <String > args = new ArrayList <>();
307
- args .add ("field.get(context)" );
308
- args .add ("source" );
309
- args .add ("context" );
310
- builder .addStatement ("return new $T($L)" , implementation , args .stream ().collect (Collectors .joining (", " )));
311
- return builder .build ();
312
- }
308
+ processFunction .args .forEach (a -> a .declareFactoryField (builder ));
313
309
314
- private MethodSpec factoryToString () {
315
- MethodSpec .Builder builder = MethodSpec .methodBuilder ("toString" ).addAnnotation (Override .class );
316
- builder .addModifiers (Modifier .PUBLIC );
317
- builder .returns (String .class );
318
- builder .addStatement ("return $S + field + $S" , declarationType .getSimpleName () + extraName + "Evaluator[field=" , "]" );
310
+ builder .addMethod (processFunction .factoryCtor ());
311
+ builder .addMethod (processFunction .factoryGet (implementation ));
312
+ builder .addMethod (processFunction .toStringMethod (implementation ));
319
313
return builder .build ();
320
314
}
321
315
}
0 commit comments