aboutsummaryrefslogtreecommitdiffstats
path: root/build/conf/proto.conf
blob: 0f906cabab220432a179b634a55e925b032c41dc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
# tag:tool-specific tag:proto
PROTOC=${tool:"contrib/tools/protoc"}
PROTOC_OLD=${tool:"contrib/tools/protoc_old"}

PY_PROTOC=${tool:"contrib/tools/protoc"}
when ($PYTHON2 == "yes") {
    PY_PROTOC=${PROTOC_OLD}
}
JAVA_PROTOC=${tool:"build/platform/java/protoc"}

when ($OPENSOURCE_REPLACE_PROTOBUF) {
    PROTOC_STYLEGUIDE_OUT=
    PROTOC_PLUGIN_STYLEGUIDE=
    PROTOBUF_INCLUDE_PATH="${protobuf_INCLUDE_DIRS}"
    DEFAULT_PROTOC_TOOLS=
}
otherwise {
    PROTOC_STYLEGUIDE_OUT=--cpp_styleguide_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE
    PROTOC_PLUGIN_STYLEGUIDE=--plugin=protoc-gen-cpp_styleguide=${tool:"contrib/tools/protoc/plugins/cpp_styleguide"}
    PROTOBUF_INCLUDE_PATH=${ARCADIA_ROOT}/contrib/libs/protobuf/src
    PROTOBUF_OLD_PATH=${ARCADIA_ROOT}/contrib/libs/protobuf_old/src
    DEFAULT_PROTOC_TOOLS=${hide;tool:"contrib/tools/protoc/bin"} ${hide;tool:"contrib/tools/protoc/plugins/cpp_styleguide"}
}
USE_VANILLA_PROTOC=no
PROTOC_TRANSITIVE_HEADERS=yes
_PROTOC_FLAGS=

# tag:proto
PY_PROTOS_FOR=no
BUILD_PROTO_AS_EVLOG=no

# tag:proto
PROTO_NAMESPACE=

# tag:proto tag:python-specific
GEN_PY_PROTOS=$YMAKE_PYTHON ${input:"build/scripts/gen_py_protos.py"} --py_ver ${_PYTHON_VER}

# tag:proto tag:cpp-specific
PROTO_HEADER_EXTS=.pb.h
CPP_PROTO_CMDLINE=
CPP_PROTO_OPTS=
CPP_PROTO_OUTS=
CPP_PROTO_OUTS_SEM=
CPP_PROTO_SUFFIXES=.pb.h .pb.cc
CPP_PROTO_PLUGINS=
CPP_PROTO_NO_DBGINFO=no

PROTOC_EXTRA_OUTS_SEM=

# tag:proto tag:cpp-specific
CPP_EV_OPTS=--plugin=protoc-gen-event2cpp=${tool:"tools/event2cpp"} --event2cpp_out=$ARCADIA_BUILD_ROOT -I=$ARCADIA_ROOT/library/cpp/eventlog
CPP_EV_OUTS=
CPP_EV_OUTS_SEM=

# tag:proto tag:python-specific
PY_PROTO_OPTS=
PY_PROTO_OUTS=
PY_PROTO_OUTS_INTERNAL=
PY_PROTO_DEPS=
PY_PROTO_SUFFIXES=_pb2.py
PY_EVLOG_SUFFIXES=_ev_pb2.py

# tag:proto tag:java-specific
JAVA_PROTO_ARGS=

# tag:proto tag:python-specific
OPTIMIZE_PY_PROTOS_FLAG=no

# tag:proto
### @usage: CPP_PROTOLIBS_DEBUG_INFO()
###
### Eqvivalent to NO_DEBUG_INFO() macro if the flag CPP_PROTO_NO_DBGINFO=yes
macro CPP_PROTOLIBS_DEBUG_INFO() {
    SET(NO_DEBUGINFO $CPP_PROTO_NO_DBGINFO)
}

# tag:internal
### @usage: _ORDER_ADDINCL([BUILD ...] [SOURCE ...] Args...) # internal
###
### Order and filter ADDINCLs (Args - is intentionally omitted in ADDINCL macro)
macro _ORDER_ADDINCL(BUILD[], SOURCE[], ARGS...) {
    ADDINCL($BUILD $SOURCE)
}

# tag:proto
### @usage: PROTO_ADDINCL([GLOBAL] [WITH_GEN] Path)
###
### This macro introduces proper ADDINCLs for .proto-files found in sources and
### .cpp/.h generated files, supplying them to appropriate commands and allowing
### proper dependency resolution at configure-time.
###
### Note: you normally shouldn't use this macro. ADDINCLs should be sent to user
### from dependency via PROTO_NAMESPACE macro
macro PROTO_ADDINCL(GLOBAL?"GLOBAL":"", Path, WITH_GEN?"BUILD":"") {
    _ORDER_ADDINCL($WITH_GEN $GLOBAL FOR proto ${ARCADIA_BUILD_ROOT}/$Path SOURCE $GLOBAL FOR proto ${ARCADIA_ROOT}/$Path)
    ADDINCL($GLOBAL ${ARCADIA_BUILD_ROOT}/$Path)
}

# tag:proto
### @usage: PROTO_NAMESPACE([WITH_GEN] Namespace)
###
### Defines protobuf namespace (import/export path prefix) which should be used for imports and
### which defines output path for .proto generation.
###
### For proper importing and configure-time dependency management it sets ADDINCLs
### for both .cpp headers includes and .proto imports. If .proto expected to be used outside of the
### processing module use GLOBAL to send proper ADDINCLs to all (transitive) users. PEERDIR to
### PROTO_LIBRARY with PROTO_NAMESPACE() is enough at user side to correctly use the library.
### If generated .proto files are going to be used for building a module than use of WITH_GEN
### parameter will add appropriate dir from the build root for .proto files search.
macro PROTO_NAMESPACE(GLOBAL?"GLOBAL":"", WITH_GEN?"WITH_GEN":"", Namespace) {
    SET(PROTO_NAMESPACE $Namespace)
    PROTO_ADDINCL(GLOBAL $WITH_GEN $Namespace)
}

# tag:proto
### @usage PROTOC_FATAL_WARNINGS()
###
### Treat protoc warnings as fatal errors that break the build, for example, unused imports
### Adds `--fatal_warnings` argument to protoc
macro PROTOC_FATAL_WARNINGS() {
    SET_APPEND(_PROTOC_FLAGS --fatal_warnings)
}

# tag:proto tag:internal tag:python-specific
### @usage: OPTIMIZE_PY_PROTOS()  # internal
###
### Enable Python proto optimization by embedding corresponding C++ code into binary.
### Python protobuf runtime will use C++ implementation instead of Python one if former is available.
### This is default mode for most PROTO_LIBRARY's and PY2_LIBRARY's, some system ones being exceptions.
macro OPTIMIZE_PY_PROTOS() {
    SET(OPTIMIZE_PY_PROTOS_FLAG yes)
}

# tag:proto tag:python-specific
### @usage: NO_OPTIMIZE_PY_PROTOS()
###
### Disable Python proto optimization using embedding corresponding C++ code into binary.
### Python protobuf runtime will use C++ implementation instead of Python one if former is available.
### This is default mode only for some system libraries.
macro NO_OPTIMIZE_PY_PROTOS() {
    SET(OPTIMIZE_PY_PROTOS_FLAG no)
}

# tag:proto tag:python-specific
macro _PROTO_PLUGIN_ARGS_BASE(Name, Tool, OutParm...) {
    .CMD=--plugin=protoc-gen-${Name}=\${tool:"$Tool"} --${Name}_out=$ARCADIA_BUILD_ROOT/\$PROTO_NAMESPACE ${pre=--${Name}_opt=:OutParm}
    .SEM=IGNORED
}

# tag:proto tag:python-specific
macro _ADD_PY_PROTO_OUT(Suf) {
    SET_APPEND(PY_PROTO_OUTS \${hide;noauto;output;norel;nopath;noext;suf=$Suf:File})
    SET_APPEND(PY_PROTO_OUTS_INTERNAL \${hide;noauto;output;norel;nopath;noext;suf=__int${_PYTHON_VER}__$Suf:File} \${hide;kv:"ext_out_name_for_\${nopath;noext;suf=__int${_PYTHON_VER}__$Suf:File} \${nopath;noext;suf=$Suf:File}"})
    # XXX fix variable expansion in plugins
    SET(PY_PROTO_SUFFIXES $PY_PROTO_SUFFIXES $Suf)
}

# tag:proto tag:python-specific
### @usage: PY_PROTO_PLUGIN(Name Ext Tool DEPS <Dependencies>)
###
### Define protoc plugin for python with given Name that emits extra output with provided Extension
### using Tool. Extra dependencies are passed via DEPS
macro PY_PROTO_PLUGIN(NAME, EXT, TOOL, DEPS[]) {
    SET_APPEND(PY_PROTO_OPTS $_PROTO_PLUGIN_ARGS_BASE($NAME $TOOL))
    _ADD_PY_PROTO_OUT($EXT)
    # XXX fix variable expansion in plugins
    SET(PY_PROTO_DEPS $PY_PROTO_DEPS $DEPS)
}

# tag:proto tag:python-specific
### @usage: PY_PROTO_PLUGIN2(Name Ext1 Ext2 Tool DEPS <Dependencies>)
###
### Define protoc plugin for python with given Name that emits 2 extra outputs with provided Extensions
### using Tool. Extra dependencies are passed via DEPS
macro PY_PROTO_PLUGIN2(NAME, EXT1, EXT2, TOOL, DEPS[]) {
    PY_PROTO_PLUGIN($NAME $EXT1 $TOOL DEPS $DEPS)
    _ADD_PY_PROTO_OUT($EXT2)
}

# tag:proto tag:java-specific
macro _JAVA_PROTO_PLUGIN_ARGS_BASE(Name, Tool, OutParm...) {
    .CMD=--plugin=protoc-gen-${Name}=\${tool:"$Tool"} --${Name}_out=$ARCADIA_BUILD_ROOT/java_out
}

# tag:proto tag:java-specific
### @usage: JAVA_PROTO_PLUGIN(Name Tool DEPS <Dependencies>)
###
### Define protoc plugin for Java with given Name that emits extra outputs
### using Tool. Extra dependencies are passed via DEPS
macro JAVA_PROTO_PLUGIN(NAME, TOOL, DEPS[]) {
    SET_APPEND(JAVA_PROTO_ARGS $_JAVA_PROTO_PLUGIN_ARGS_BASE($NAME $TOOL))
    # XXX fix variable expansion in plugins
    SET(JAVA_PROTOBUF_PEERS $JAVA_PROTOBUF_PEERS $DEPS)
}

macro _ADD_SEM_PROP_IF_NON_EMPTY(Prop, Args...) {
    .SEM=${pre=&& set_target_property $Prop :Args} ${pre=&& target_properties-ITEM && target_properties-name $Prop && target_properties-value :Args}
}

# tag:proto tag:java-specific
macro WITH_KOTLIN_GRPC() {
    ENABLE(KOTLIN_PROTO)
    PEERDIR(build/platform/java/kotlin_grpc)
    SET_APPEND(JAVA_PROTO_ARGS ${env:"JAVA_HOME=${JDK_RESOURCE}"} ${env:"KOTLIN_GRPC_JAR=${KOTLIN_GRPC_RESOURCE_GLOBAL}/grpc_kotlin/protoc-gen-grpc-kotlin-1.3.1.jar"} --plugin=protoc-gen-kotlin_grpc=${KOTLIN_GRPC_RESOURCE_GLOBAL}/grpc_kotlin/grpc_kotlin --kotlin_grpc_out=$ARCADIA_BUILD_ROOT/java_out)
    SET(JAVA_PROTOBUF_PEERS $JAVA_PROTOBUF_PEERS contrib/java/io/grpc/grpc-kotlin-stub/1.3.1)
    SET(JAVA_PROTOBUF_PEERS $JAVA_PROTOBUF_PEERS contrib/java/com/google/protobuf/protobuf-kotlin/${JAVA_PROTO_RUNTIME_VERSION})
}


# tag:proto tag:cpp-specific
macro _ADD_CPP_PROTO_OUT(Suf) {
    .SEM=append_target_property PROTOC_EXTRA_OUTS $Suf ${hide;output;suf=.o:Suf} $_ADD_SEM_PROP_IF_NON_EMPTY(PROTO_NAMESPACE $PROTO_NAMESPACE)
    SET_APPEND(CPP_PROTO_OUTS \${output;norel;nopath;noext;suf=$Suf:File})
    SET_APPEND(PROTOC_EXTRA_OUTS_SEM && protoc_extra_outs $Suf)

    # XXX fix variable expansion in plugins
    SET(CPP_PROTO_SUFFIXES $CPP_PROTO_SUFFIXES $Suf)
}

# tag:proto tag:cpp-specific
HAS_CPP_PROTOBUF_PEERS=no
CPP_PROTOBUF_PEERS=

# tag:proto tag:cpp-specific
### @usage: CPP_PROTO_PLUGIN0(Name Tool [DEPS <Dependencies>] [EXTRA_OUT_FLAG <ExtraOutFlag>])
###
### Define protoc plugin for C++ with given Name that emits code into regular outputs
### using Tool. Extra dependencies are passed via DEPS.
macro CPP_PROTO_PLUGIN0(NAME, TOOL, DEPS[], EXTRA_OUT_FLAG="") {
    .SEM=target_proto_plugin $NAME ${tool;rootrel:TOOL} ${hide;output;suf=.fake.o:NAME} && target_macroses-ITEM && target_macroses-macro target_proto_plugin && target_macroses-args $NAME ${tool;rootrel:TOOL} ${hide;output;suf=.fake.o:NAME}
    SET_APPEND(CPP_PROTO_OPTS $_PROTO_PLUGIN_ARGS_BASE($NAME $TOOL $EXTRA_OUT_FLAG))

    # XXX fix variable expansion in plugins
    ENABLE(HAS_CPP_PROTOBUF_PEERS)
    SET(CPP_PROTOBUF_PEERS $CPP_PROTOBUF_PEERS $DEPS)
}

# tag:proto tag:cpp-specific
### @usage: CPP_PROTO_PLUGIN(Name Tool Suf [DEPS <Dependencies>] [EXTRA_OUT_FLAG <ExtraOutFlag>])
###
### Define protoc plugin for C++ with given Name that emits code into 1 extra output
### using Tool. Extra dependencies are passed via DEPS.
macro CPP_PROTO_PLUGIN(NAME, TOOL, SUF, DEPS[], EXTRA_OUT_FLAG="") {
    CPP_PROTO_PLUGIN0($NAME $TOOL DEPS $DEPS ${pre=EXTRA_OUT_FLAG :EXTRA_OUT_FLAG})

    _ADD_CPP_PROTO_OUT($SUF)
}

# tag:proto tag:cpp-specific
### @usage: CPP_PROTO_PLUGIN2(Name Tool Suf1 Suf2 [DEPS <Dependencies>] [EXTRA_OUT_FLAG <ExtraOutFlag>])
###
### Define protoc plugin for C++ with given Name that emits code into 2 extra outputs
### using Tool. Extra dependencies are passed via DEPS.
macro CPP_PROTO_PLUGIN2(NAME, TOOL, SUF1, SUF2, DEPS[], EXTRA_OUT_FLAG="") {
    CPP_PROTO_PLUGIN($NAME $TOOL $SUF1 DEPS $DEPS ${pre=EXTRA_OUT_FLAG :EXTRA_OUT_FLAG})

    _ADD_CPP_PROTO_OUT($SUF2)
    SET_APPEND(CPP_PROTO_OUTS_SEM \${hide;output;norel;nopath;noext;suf=$SUF2:File})
}

# tag:proto
### @usage: USE_SKIFF() #wip, do not use
###
### Use mapreduce/yt/skiff_proto/plugin for C++
macro USE_SKIFF() {
    # Move extra includes to INDUCED_DEPS macro in mapreduce/yt/skiff_proto/plugin/ya.make
    CPP_PROTO_PLUGIN0(skiff mapreduce/yt/skiff_proto/plugin DEPS mapreduce/yt/skiff_proto/lib)
}

# tag:go-specific
_GO_COMMON_GOOGLE_APIS = \
vendor/google.golang.org/genproto/googleapis/api/annotations \
vendor/google.golang.org/genproto/googleapis/api/configchange \
vendor/google.golang.org/genproto/googleapis/api/distribution \
vendor/google.golang.org/genproto/googleapis/api/expr/v1alpha1 \
vendor/google.golang.org/genproto/googleapis/api/expr/v1beta1 \
vendor/google.golang.org/genproto/googleapis/api/httpbody \
vendor/google.golang.org/genproto/googleapis/api/label \
vendor/google.golang.org/genproto/googleapis/api/metric \
vendor/google.golang.org/genproto/googleapis/api/monitoredres \
vendor/google.golang.org/genproto/googleapis/api/serviceconfig \
vendor/cloud.google.com/go/servicecontrol/apiv1/servicecontrolpb \
vendor/cloud.google.com/go/servicemanagement/apiv1/servicemanagementpb \
vendor/google.golang.org/genproto/googleapis/iam/admin/v1 \
vendor/google.golang.org/genproto/googleapis/iam/credentials/v1 \
vendor/google.golang.org/genproto/googleapis/iam/v1 \
vendor/google.golang.org/genproto/googleapis/iam/v1/logging \
vendor/google.golang.org/genproto/googleapis/logging/type \
vendor/google.golang.org/genproto/googleapis/logging/v2 \
vendor/google.golang.org/genproto/googleapis/rpc/code \
vendor/google.golang.org/genproto/googleapis/rpc/errdetails \
vendor/google.golang.org/genproto/googleapis/rpc/status \
vendor/google.golang.org/genproto/googleapis/type/calendarperiod \
vendor/google.golang.org/genproto/googleapis/type/color \
vendor/google.golang.org/genproto/googleapis/type/date \
vendor/google.golang.org/genproto/googleapis/type/dayofweek \
vendor/google.golang.org/genproto/googleapis/type/expr \
vendor/google.golang.org/genproto/googleapis/type/fraction \
vendor/google.golang.org/genproto/googleapis/type/latlng \
vendor/google.golang.org/genproto/googleapis/type/money \
vendor/google.golang.org/genproto/googleapis/type/postaladdress \
vendor/google.golang.org/genproto/googleapis/type/quaternion \
vendor/google.golang.org/genproto/googleapis/type/timeofday

# tag:go-specific
_COMMON_GOOGLE_APIS=None

# tag:go-specific
### @usage: USE_COMMON_GOOGLE_APIS([apis...])
###
### Use common-google-apis library set. Pass optional apis list to be used or use them all.
### This macro is properly handled for all languages including Go, where apis come in
## pregenerated form. In other languages apis are generated from sources in Arcadia.
macro USE_COMMON_GOOGLE_APIS(APIS...) {
    SET(_COMMON_GOOGLE_APIS ${pre=vendor/google.golang.org/genproto/googleapis/:APIS})
}

# tag:go-specific tag:proto
GO_PROTO_GEN_PLUGINS=
GO_PROTO_OPTS=
GO_PROTO_OUTS=
GO_PROTO_GRPC_OPTS=
GO_PROTO_GRPC_OUTS=
GO_PROTO_V2=no
_GO_PROTO_CHECK_OUTPUT=

# tag:go-specific tag:proto
GO_PROTOBUF_IMPORTS=\
    ${GOSTD}/sync \
    ${GOSTD}/reflect \
    ${GOSTD}/fmt \
    ${GOSTD}/math \
    vendor/github.com/golang/protobuf/proto \
    vendor/google.golang.org/protobuf/types/descriptorpb \
    vendor/google.golang.org/protobuf/runtime/protoimpl \
    vendor/google.golang.org/protobuf/runtime/protoiface \
    vendor/google.golang.org/protobuf/reflect/protoreflect

# tag:go-specific tag:proto
GO_PROTOBUF_WELLKNOWN_TYPES=\
    vendor/google.golang.org/protobuf/types/known/anypb \
    vendor/google.golang.org/protobuf/types/known/apipb \
    vendor/google.golang.org/protobuf/types/known/durationpb \
    vendor/google.golang.org/protobuf/types/known/emptypb \
    vendor/google.golang.org/protobuf/types/known/fieldmaskpb \
    vendor/google.golang.org/protobuf/types/known/sourcecontextpb \
    vendor/google.golang.org/protobuf/types/known/structpb \
    vendor/google.golang.org/protobuf/types/known/timestamppb \
    vendor/google.golang.org/protobuf/types/known/typepb \
    vendor/google.golang.org/protobuf/types/known/wrapperspb

# tag:go-specific tag:proto
### @usage: GO_PROTO_PLUGIN(Name Ext Tool [DEPS dependencies...])
###
### Define protoc plugin for GO with given Name that emits extra output with provided extension
### Ext using Tool. Extra dependencies are passed via DEPS.
macro GO_PROTO_PLUGIN(NAME, EXT, TOOL, DEPS[]) {
    SET_APPEND(GO_PROTO_OPTS $_PROTO_PLUGIN_ARGS_BASE($NAME $TOOL))
    SET_APPEND(GO_PROTO_OUTS \${hide;noauto;output;norel;nopath;noext;suf=$EXT:File})
    PEERDIR(${DEPS})
}

# tag:go-specific tag:proto
GO_PROTO_CMDLINE=${cwd;rootdir;input:File} $YMAKE_PYTHON3 ${input:"build/scripts/go_proto_wrapper.py"} --arcadia-prefix $GO_ARCADIA_PROJECT_PREFIX --contrib-prefix $GO_CONTRIB_PROJECT_PREFIX --namespace ./$PROTO_NAMESPACE $_GO_PROTO_CHECK_OUTPUT --proto ${input;rootrel:File} -- $PROTOC -I=./$PROTO_NAMESPACE -I=$ARCADIA_ROOT/$PROTO_NAMESPACE ${pre=-I=:_PROTO__INCLUDE} -I=$ARCADIA_BUILD_ROOT -I=$PROTOBUF_INCLUDE_PATH $_PROTOC_FLAGS ${hide:PROTO_FAKEID}

# tag:go-specific tag:proto
macro _GO_PROTO_CMD_IMPL(File, OPTS...) {
    .CMD=$GO_PROTO_CMDLINE $OPTS ${hide;kv:"p PB"} ${hide;kv:"pc yellow"}
    .PEERDIR=${GO_PROTOBUF_IMPORTS} ${GO_PROTOBUF_WELLKNOWN_TYPES}
    .ADDINCL=FOR proto ${PROTOBUF_INCLUDE_PATH}
}

# tag:go-specific tag:proto
macro _GO_PROTO_CMD(File) {
    .CMD=$_GO_PROTO_CMD_IMPL($File $GO_PROTO_OPTS $GO_PROTO_OUTS)
}

# tag:proto
### @usage: YT_ORM_PROTO_YSON(Files... OUT_OPTS Opts...)
###
### Generate .yson.go from .proto using yt/yt/orm/go/codegen/yson/internal/proto-yson-gen/cmd/proto-yson-gen
macro YT_ORM_PROTO_YSON(OUT_OPTS[], Files...) {
    .CMD=${cwd:BINDIR} $PROTOC --plugin=protoc-gen-custom=${tool:"yt/yt/orm/go/codegen/yson/internal/proto-yson-gen/cmd/proto-yson-gen"} -I=${ARCADIA_ROOT}/${PROTO_NAMESPACE} ${pre=-I=:_PROTO__INCLUDE} -I=${ARCADIA_ROOT} --custom_out="$OUT_OPTS paths=base_name:." --custom_opt="goroot=${GO_TOOLS_ROOT}" $_PROTOC_FLAGS ${input:Files} ${hide;noauto;output;nopath;noext;suf=.yson.go:Files} ${hide:PROTO_FAKEID}
    .ADDINCL=FOR proto ${ARCADIA_ROOT}/${MODDIR} FOR proto ${ARCADIA_ROOT}/${GO_TEST_IMPORT_PATH} FOR proto yt ${ARCADIA_BUILD_ROOT}/yt FOR proto ${PROTOBUF_INCLUDE_PATH}
    .PEERDIR=$GOSTD/strings $GOSTD/fmt $GOSTD/errors $GOSTD/encoding/json library/go/core/xerrors yt/go/yson yt/go/yterrors yt/yt/orm/go/codegen/yson/ytypes contrib/libs/protobuf

}

_SEM_CPP_PROTO_CMD=target_proto_messages PRIVATE ${input:File} \
                   && target_options-privates-ITEM && target_options-privates-option target_proto_messages && target_options-privates-args ${input:File} \
                   $CPP_PROTO_OUTS_SEM ${hide;output;suf=${OBJ_SUF}.pb.o:File} $DEFAULT_PROTOC_TOOLS \
                   $PROTOC_EXTRA_OUTS_SEM \
                   && set_global_flags COMMON_PROTOC_FLAGS \
                   && platform_vars-COMMON_PROTOC_FLAGS "" \
                   && target_proto_outs --cpp_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE $PROTOC_STYLEGUIDE_OUT \
                   && target_macroses-ITEM && target_macroses-macro target_proto_outs && target_macroses-args --cpp_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE $PROTOC_STYLEGUIDE_OUT \
                   && target_proto_addincls ./$PROTO_NAMESPACE $ARCADIA_ROOT/$PROTO_NAMESPACE ${_PROTO__INCLUDE} $ARCADIA_BUILD_ROOT $PROTOBUF_INCLUDE_PATH \
                   && target_macroses-ITEM && target_macroses-macro target_proto_addincls && target_macroses-args ./$PROTO_NAMESPACE $ARCADIA_ROOT/$PROTO_NAMESPACE ${_PROTO__INCLUDE} $ARCADIA_BUILD_ROOT $PROTOBUF_INCLUDE_PATH

# tag:proto
macro _CPP_PROTO_CMD(File) {
    .CMD=$CPP_PROTO_CMDLINE $CPP_PROTO_OPTS ${hide;kv:"p PB"} ${hide;kv:"pc yellow"}
    .SEM=$_SEM_CPP_PROTO_CMD
    .PEERDIR=contrib/libs/protobuf
}

# tag:proto
macro _CPP_VANILLA_PROTO_CMD(File) {
    .CMD=$CPP_PROTO_CMDLINE $CPP_PROTO_OPTS ${hide;kv:"p PB"} ${hide;kv:"pc yellow"}
    .PEERDIR=contrib/libs/protobuf_std
}

_SEM_CPP_EV_CMD=target_ev_messages PRIVATE ${input:File} \
                   && target_options-privates-ITEM && target_options-privates-option target_ev_messages && target_options-privates-args ${input:File} \
                   $CPP_EV_OUTS_SEM ${hide;output;suf=${OBJ_SUF}.pb.o:File} ${hide;tool:"tools/event2cpp/bin"} $DEFAULT_PROTOC_TOOLS \
                   && set_global_flags COMMON_PROTOC_FLAGS \
                   && platform_vars-COMMON_PROTOC_FLAGS "" \
                   && target_proto_outs --cpp_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE $PROTOC_STYLEGUIDE_OUT --event2cpp_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE \
                   && target_macroses-ITEM && target_macroses-macro target_proto_outs && target_macroses-args --cpp_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE $PROTOC_STYLEGUIDE_OUT --event2cpp_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE \
                   && target_proto_addincls ./$PROTO_NAMESPACE $ARCADIA_ROOT/$PROTO_NAMESPACE ${_PROTO__INCLUDE} $ARCADIA_BUILD_ROOT $PROTOBUF_INCLUDE_PATH $ARCADIA_ROOT/library/cpp/eventlog \
                   && target_macroses-ITEM && target_macroses-macro target_proto_addincls && target_macroses-args ./$PROTO_NAMESPACE $ARCADIA_ROOT/$PROTO_NAMESPACE ${_PROTO__INCLUDE} $ARCADIA_BUILD_ROOT $PROTOBUF_INCLUDE_PATH $ARCADIA_ROOT/library/cpp/eventlog

# tag:proto
macro _CPP_EVLOG_CMD(File) {
    .CMD=$CPP_EV_CMDLINE $CPP_EV_OPTS ${hide;kv:"p EV"} ${hide;kv:"pc yellow"}
    .SEM=$_SEM_CPP_EV_CMD
    .PEERDIR=library/cpp/eventlog contrib/libs/protobuf
}

# tag:proto
macro _CPP_PROTO_EVLOG_CMD(File) {
    # process .proto as .ev
    .CMD=$CPP_PROTO_CMDLINE $CPP_EV_OPTS ${hide;kv:"p PB"} ${hide;kv:"pc yellow"}
    .PEERDIR=library/cpp/eventlog contrib/libs/protobuf
}

# tag:proto
macro _CPP_CFGPROTO_CMD(File) {
    # keep extension in output just as in EV: this is hard-coded behaviour of protoc for non-.proto extensions
    .CMD=$CPP_EV_CMDLINE  --plugin=protoc-gen-config=${tool:"library/cpp/proto_config/plugin"} --config_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE ${hide;kv:"p PB"} ${hide;kv:"pc yellow"}
    .PEERDIR=library/cpp/proto_config/codegen library/cpp/proto_config/protos contrib/libs/protobuf
}

# tag:proto
PY_PROTO_MYPY_ENABLED=yes
PY_PROTO_MYPY_PLUGIN_BASE=--plugin=protoc-gen-mypy=${tool:"contrib/python/mypy-protobuf/bin/protoc-gen-mypy"} --mypy_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE

# tag:proto tag:python-specific
PY_PROTO_MYPY_SUFFIX=
PY_PROTO_MYPY_PLUGIN=
PY_PROTO_MYPY_PLUGIN_INTERNAL=

# tag:proto tag:python-specific
macro NO_MYPY() {
    DISABLE(PY_PROTO_MYPY_ENABLED)
}

# tag:proto tag:python-specific
macro _PY_PROTO_CMD_BASE(File, Suf, Args...) {
    .CMD=$PY_PROTOC -I=./$PROTO_NAMESPACE -I=$ARCADIA_ROOT/$PROTO_NAMESPACE ${pre=-I=:_PROTO__INCLUDE} -I=$ARCADIA_BUILD_ROOT -I=$PROTOBUF_INCLUDE_PATH --python_out=$ARCADIA_BUILD_ROOT/$PROTO_NAMESPACE $_PROTOC_FLAGS ${input;rootrel:File} ${output;main;hide;noauto;norel;nopath;noext;suf=$Suf:File} ${hide;kv:"p PB"} ${hide;kv:"pc yellow"} $Args ${hide:PROTO_FAKEID}
}

# tag:proto tag:python-specific
macro _PY_PROTO_CMD(File) {
    .CMD=${cwd;rootdir;input:File} $_PY_PROTO_CMD_BASE($File _pb2.py $PY_PROTO_OPTS $PY_PROTO_OUTS $PY_PROTO_MYPY_PLUGIN)
}

# tag:proto tag:python-specific
macro _PY_PROTO_CMD_INTERNAL(File) {
    .CMD=${cwd;rootdir;input:File} $GEN_PY_PROTOS --suffixes $PY_PROTO_SUFFIXES $PY_PROTO_MYPY_SUFFIX --input ${input;rootrel:File} --ns /$PROTO_NAMESPACE -- $_PY_PROTO_CMD_BASE($File __int${_PYTHON_VER}___pb2.py $PY_PROTO_OPTS $PY_PROTO_OUTS_INTERNAL ${hide;kv:"ext_out_name_for_${nopath;noext;suf=__int${_PYTHON_VER}___pb2.py:File} ${nopath;noext;suf=_pb2.py:File}"} $PY_PROTO_MYPY_PLUGIN_INTERNAL)
}

# tag:proto tag:java-specific
JAVA_PROTO_RUNTIME=

# tag:proto tag:java-specific
### @usage: USE_JAVALITE()
### Use protobuf-javalite for Java
macro USE_JAVALITE() {
    SET(JAVA_PROTO_RUNTIME javalite)
}

# tag:proto tag:java-specific
JAVA_PROTO_COMPILER_VERSION = 3.25.3
JAVA_PROTO_RUNTIME_VERSION = 3.25.3
JAVA_PROTO_COMMON_VERSION = 2.9.0
JAVA_GRPC_VERSION = 1.51.0
JAVA_NETTY_NETTY_VERSION = 4.1.79.Final
KOTLIN_PROTO=no
KOTLIN_PROTO_PEERS=
when ($JAVA_PROTO_RUNTIME == "javalite") {
    _JAVA_PROTO_LITE_ARG=lite:
    JAVA_PROTOBUF_PEERS=contrib/java/com/google/protobuf/protobuf-javalite/${JAVA_PROTO_RUNTIME_VERSION} ${KOTLIN_PROTO_PEERS}
    JAVA_GRPC_STUB=contrib/java/io/grpc/grpc-stub/${JAVA_GRPC_VERSION}
    JAVA_GRPC_PROTOBUF=contrib/java/io/grpc/grpc-protobuf/${JAVA_GRPC_VERSION}
}
otherwise {
    _JAVA_PROTO_LITE_ARG=
    JAVA_PROTOBUF_PEERS=contrib/java/com/google/protobuf/protobuf-java/${JAVA_PROTO_RUNTIME_VERSION} ${KOTLIN_PROTO_PEERS}
    JAVA_GRPC_STUB=contrib/java/io/grpc/grpc-stub/${JAVA_GRPC_VERSION}
    JAVA_GRPC_PROTOBUF=contrib/java/io/grpc/grpc-protobuf/${JAVA_GRPC_VERSION}
}

KOTLIN_PROTO_FLAGS=
# tag:proto tag:java-specific
macro _JAVA_PROTO_CMD(File) {
    .CMD=${cwd;rootdir;input:File} $YMAKE_PYTHON ${input:"build/scripts/tared_protoc.py"} --tar-output ${output;norel;nopath;noext;suf=.jsrc:File} --protoc-out-dir $ARCADIA_BUILD_ROOT/java_out $JAVA_PROTOC -I=./$PROTO_NAMESPACE ${pre=-I=:_PROTO__INCLUDE} -I=$ARCADIA_ROOT --java_out=${_JAVA_PROTO_LITE_ARG}$ARCADIA_BUILD_ROOT/java_out ${KOTLIN_PROTO_FLAGS} $_PROTOC_FLAGS ${input;rootrel:File} ${hide;kv:"p PB"} ${hide;kv:"pc yellow"} $JAVA_PROTO_ARGS ${hide:PROTO_FAKEID}
    .SEM=proto_files ${input;rootrel:File} ${hide;output:File.jsrc}
}


# tag:proto tag:perl-specific tag:deprecated
### @usage: XS_PROTO(InputProto Dir Outputs...) # deprecated
###
### Generate Perl code from protobuf.
### In order to use this macro one should predict all outputs protoc will emit from input_proto file and enlist those as outputs.
macro XS_PROTO(File, Dir, Outputs...) {
    .CMD=${PROTOC_OLD} -I=${ARCADIA_ROOT}/${Dir} ${pre=-I=:_PROTO__INCLUDE} -I=${ARCADIA_ROOT} -I=${PROTOBUF_OLD_PATH} --perlxs_out=${BINDIR} $_PROTOC_FLAGS ${input:File} ${hide;output:Outputs} ${induced_deps=h+cpp;hide;nopath;noext;suf=.pb.h:File} ${hide:PROTO_FAKEID}
    PEERDIR(${Dir})
    ADDINCL(${ARCADIA_BUILD_ROOT}/${Dir})
}

# tag:proto tag:python-specific
when ($PY_PROTOS_FOR == "yes") {
    PEERDIR+=contrib/libs/protobuf/python
}

# tag:python-specific
macro _PY_EVLOG_CMD_BASE(File, Suf, Args...) {
    .CMD=$_PY_PROTO_CMD_BASE($File $Suf $Args)
    .PEERDIR=library/cpp/eventlog/proto
}

# tag:python-specific tag:proto
macro _PY_EVLOG_CMD(File) {
    .CMD=${cwd;rootdir;input:File} $_PY_EVLOG_CMD_BASE($File _ev_pb2.py)
}

# tag:python-specific tag:proto
macro _PY_EVLOG_CMD_INTERNAL(File) {
    .CMD=${cwd;rootdir;input:File} $GEN_PY_PROTOS --suffixes $PY_EVLOG_SUFFIXES --input ${input;rootrel:File} --ns /$PROTO_NAMESPACE -- $_PY_EVLOG_CMD_BASE($File __int${_PYTHON_VER}___ev_pb2.py ${hide;kv:"ext_out_name_for_${nopath;noext;suf=__int${_PYTHON_VER}___ev_pb2.py:File} ${nopath;noext;suf=_ev_pb2.py:File}"})
}

# tag:java-specific tag:proto
macro _JAVA_EVLOG_CMD(File) {
    .CMD=$COPY_CMD ${input:File} ${output;nopath;noext;norel;suf=_ev.proto:File} ${hide;kv:"p EV"} ${hide;kv:"pc yellow"}
    .PEERDIR=library/cpp/eventlog/proto
}

# tag:proto tag:grpc
_GRPC_ENABLED=no
_GRPC_SUF_CC=.grpc.pb.cc
_GRPC_SUF_H=.grpc.pb.h

# tag:proto tag:grpc
### @usage: GRPC()
###
### Emit GRPC code for all .proto files in a PROTO_LIBRARY.
### This works for all available PROTO_LIBRARY versions (C++, Python 2.x, Python 3.x, Java and Go).
macro GRPC() {
    ENABLE(_GRPC_ENABLED)

    # C++
    CPP_PROTO_PLUGIN2(grpc_cpp contrib/tools/protoc/plugins/grpc_cpp $_GRPC_SUF_CC $_GRPC_SUF_H DEPS contrib/libs/grpc $_GRPC_GMOCK_OUTFLAG)

    # Python
    PY_PROTO_PLUGIN(grpc_py _pb2_grpc.py contrib/tools/protoc/plugins/grpc_python DEPS contrib/python/grpcio)

    # Java
    JAVA_PROTO_PLUGIN(grpc_java build/platform/java/grpc DEPS $JAVA_GRPC_STUB $JAVA_GRPC_PROTOBUF)
    SET_APPEND(JAVA_PROTOBUF_PEERS contrib/java/javax/annotation/javax.annotation-api/1.3.1)
}

# tag:proto tag:grpc
_GRPC_GMOCK_OUTFLAG=

# tag:proto tag:grpc
### @usage: WITH_GMOCK()
###
### Enable generating *_mock.grpc.pb.cc/h files
macro GRPC_WITH_GMOCK() {
    SET(_GRPC_GMOCK_OUTFLAG EXTRA_OUT_FLAG generate_mock_code=true)
    GRPC()
    _ADD_CPP_PROTO_OUT(_mock$_GRPC_SUF_H)
    SET_APPEND(CPP_PROTO_OUTS_SEM ${hide;output;norel;nopath;noext;suf=_mock$_GRPC_SUF_H:File})
}

macro GO_PROTO_USE_V2() {
    ENABLE(GO_PROTO_V2)
}

# tag:proto
### @usage: RESOLVE_PROTO()
###
### Enable include resolving within UNIONs and let system .proto being resolved
### among .proto/.gztproto imports
###
### Note: it is currently impossible to enable resolving only for .proto, so resolving is enabled for all supported files
### also we only add ADDINCL for stock protobuf. So use this macro with care: it may cause resolving problems those are
### to be addressed by either ADDINCLs or marking them as TEXT. Please contact devtools for details.
macro RESOLVE_PROTO() {
    SET(DONT_RESOLVE_INCLUDES no)
    ADDINCL(FOR proto $PROTOBUF_INCLUDE_PATH)
}

# tag:python-specific tag:proto tag:deprecated
### @usage GENERATE_PY_PROTOS(ProtoFiles...) # deprecated
###
### Generate python bindings for protobuf files.
### Macro is obsolete and not recommended for use!
macro GENERATE_PY_PROTOS(FILES...) {
    foreach (FILE : $FILES) {
        _PY_PROTO_CMD($FILE)
    }
}

# tag:python-specific tag:proto
macro _GENERATE_PY_PROTOS_INTERNAL(FILES...) {
    foreach (FILE : $FILES) {
        _PY_PROTO_CMD_INTERNAL($FILE)
    }
}

# tag:python-specific
macro _GENERATE_PY_EVS_INTERNAL(FILES...) {
    foreach (FILE : $FILES) {
        _PY_EVLOG_CMD_INTERNAL($FILE)
    }
}

### @usage: LIST_PROTO([TO list.proto] Files...)  # deprecated
###
### Create list of .proto files in a list-file (should be .proto, files.proto by default)
### with original .proto-files as list's dependencies.
###
### This allows to process files listed, passing list as an argument to the processor
###
### TODO: proper implementation needed
macro LIST_PROTO(TO="files.proto", Files...) {
    .CMD=$YMAKE_PYTHON3 ${input:"build/scripts/list.py"} ${Files} ${hide;input:Files} ${stdout;noauto;output:TO} ${output_include;from_input;hide:Files}
    _COMPILE_LIST_PROTO(${TO})
    _EXPOSE(${TO})
}

macro _COMPILE_LIST_PROTO(SRC) {
    .CMD=$YMAKE_PYTHON ${input:"build/scripts/touch.py"} ${hide;input:SRC} ${output;noext;suf=.pb.h:SRC}
}

# tag:proto
macro _PROTO_DESC_RAWPROTO_CMD(File) {
    .CMD=${cwd;rootdir;input:File} $YMAKE_PYTHON3 ${input:"build/scripts/desc_rawproto_wrapper.py"} --desc-output ${output;suf=.desc:File} --rawproto-output ${output;norel;suf=.${_MODDIR_HASH}.rawproto:File} --proto-file ${input;rootrel:File} -- $PROTOC -I=./$PROTO_NAMESPACE -I=$ARCADIA_ROOT/$PROTO_NAMESPACE ${pre=-I=:_PROTO__INCLUDE} -I=$ARCADIA_BUILD_ROOT -I=$PROTOBUF_INCLUDE_PATH --include_source_info $_PROTOC_FLAGS ${hide:PROTO_FAKEID}
}

_PROTO_DESC_MERGE_CMD=$YMAKE_PYTHON3 ${input:"build/scripts/merge_files.py"} $TARGET ${ext=.desc:AUTO_INPUT} ${hide;kv:"p PD"} ${hide;kv:"pc light-cyan"} && ${cwd:ARCADIA_BUILD_ROOT} $YMAKE_PYTHON3 ${input:"build/scripts/collect_rawproto.py"} --output ${output;suf=.protosrc:REALPRJNAME} ${rootrel;ext=.rawproto:AUTO_INPUT}
_PROTO_DESC_MERGE_PEERS_CMD=$YMAKE_PYTHON3 ${input:"build/scripts/merge_files.py"} $TARGET $PEERS ${ext=.protodesc:SRCS_GLOBAL}  ${hide;kv:"p PD"} ${hide;kv:"pc light-cyan"} && ${cwd:ARCADIA_BUILD_ROOT} $YMAKE_PYTHON3 ${input:"build/scripts/merge_protosrc.py"} --output ${output;suf=.tar:REALPRJNAME} ${rootrel:PEERS}

NEED_GOOGLE_PROTO_PEERDIRS=yes

CPP_PROTO_LIBRARY_SEM=$CPP_LIBRARY_SEM

JAVA_PROTO_LIBRARY_SEM=$BUILD_PROTO_JAR_SEM $_GRADLE_EXPORT_PUBLISHING_SEM

# tag:proto
### @usage: PROTO_LIBRARY()
###
### Build some varian of protocol buffers library.
###
### The particular variant is selected based on where PEERDIR to PROTO_LIBRARY comes from.
###
### Now supported 5 variants: C++, Java, Python 2.x, Python 3.x and Go.
### When PEERDIR comes from module for particular language appropriate variant is selected.
### PROTO_LIBRARY also supports emission of GRPC code if GRPC() macro is specified.
### Notes:
### - Python versions emit C++ code in addition to Python as optimization.
### - In some PROTO_LIBRARY-es Java or Python versions are excluded via EXCLUDE_TAGS macros due to incompatibilities.
### - Use from DEPENDS or BUNDLE is not allowed
###
### Documentation: https://wiki.yandex-team.ru/yatool/proto_library/
###
### See: [GRPC()](#macro_GRPC), [OPTIMIZE_PY_PROTOS()](#macro_OPTIMIZE_PY_PROTOS), [INCLUDE_TAGS()](#macro_INCLUDE_TAGS), [EXCLUDE_TAGS()](#macro_EXCLUDE_TAGS)
multimodule PROTO_LIBRARY {
    module CPP_PROTO : LIBRARY {
        .ALLOWED=_EXPOSE LIST_PROTO
        # TODO(svidyuk): think about marker which forces semantics inheritance
        .SEM=CPP_PROTO_LIBRARY_SEM
        FORCE_COVERAGE_DISABLED=yes
        ENABLE(CPP_PROTO)
        ENABLE(GEN_PROTO)
        NO_CLANG_TIDY()
        CPP_PROTOLIBS_DEBUG_INFO()
        SET(PEERDIR_TAGS CPP_PROTO)

        when ($BUILD_PROTO_AS_EVLOG == "yes" && $USE_VANILLA_PROTOC == "yes") {
            _OK=no
        }
        ASSERT(_OK BUILD_PROTO_AS_EVLOG and USE_VANILLA_PROTOC are incompatible yet)

        MODULE_SUFFIX=$_CPP_PROTO_MODULE_SUFFIX
        MODULE_PREFIX=$_CPP_PROTO_MODULE_PREFIX

        when ($_COMMON_GOOGLE_APIS != "None") {
            PEERDIR += contrib/libs/googleapis-common-protos
        }
    }

    module JAVA_PROTO: EXTERNAL_JAVA_LIBRARY {
        .EXTS=.jsrc
        .ALLOWED=GRPC
        .SEM=JAVA_PROTO_LIBRARY_SEM
        SET(PEERDIR_TAGS JAVA JAVA_PROTO)
        ENABLE(JAVA_PROTO)
        DISABLE(_NEED_SBOM_INFO)
        PEERDIR+=$JAVA_PROTOBUF_PEERS

        when ($KOTLIN_PROTO == "yes") {
            KOTLIN_PROTO_PEERS=contrib/java/com/google/protobuf/protobuf-kotlin/${JAVA_PROTO_RUNTIME_VERSION}
            KOTLIN_PROTO_FLAGS=--kotlin_out=$ARCADIA_BUILD_ROOT/java_out
        }
        when ($GRADLE_EXPORT_PUBLISHING == "yes") {
            _GRADLE_EXPORT_PUBLISHING_SEM=$_DO_GRADLE_EXPORT_PUBLISHING_SEM
        }

        .IGNORED=GENERATE_ENUM_SERIALIZATION GENERATE_ENUM_SERIALIZATION_WITH_HEADER USE_SKIFF CPP_PROTO_PLUGIN2 PY_PROTO_PLUGIN YMAPS_SPROTO RESOURCE
        ADDINCL(FOR proto $PROTOBUF_INCLUDE_PATH)

        when ($_COMMON_GOOGLE_APIS != "None") {
            PEERDIR += contrib/java/com/google/api/grpc/proto-google-common-protos/${JAVA_PROTO_COMMON_VERSION}
            ADDINCL += GLOBAL FOR proto ${ARCADIA_ROOT}/contrib/libs/googleapis-common-protos
        }
    }

    module PY_PROTO: PY2_LIBRARY {
        .ALIASES=SRCS=PY_SRCS
        .ALLOWED=OPTIMIZE_PY_PROTOS NO_OPTIMIZE_PY_PROTOS
        .PEERDIRSELF=CPP_PROTO
        .SEM=IGNORED
        SET(PEERDIR_TAGS PY2 PY_PROTO)
        ENABLE(PY_PROTO)
        DISABLE(_NEED_SBOM_INFO)
        OPTIMIZE_PY_PROTOS()
        OBJ_SUF=.py2
        # Can not use NO_LINT(), because is not allowed outside of contrib directory
        SET(_NO_LINT_VALUE none_internal)

        when ($_COMMON_GOOGLE_APIS != "None") {
            PEERDIR += contrib/libs/googleapis-common-protos
        }

        _IGNORE_SELF_PEERS=
        _CPP_PROTO_LIBRARY=${MODDIR}/$_CPP_PROTO_MODULE_PREFIX$REALPRJNAME$_CPP_PROTO_MODULE_SUFFIX
        when ($OPTIMIZE_PY_PROTOS_FLAG == "no") {
            _IGNORE_PEERDIRSELF=CPP_PROTO
        }
        SET_APPEND(_WHOLE_ARCHIVE_LIBS_VALUE_GLOBAL $_CPP_PROTO_LIBRARY)
    }

    module PY3_PROTO: PY3_LIBRARY {
        .ALIASES=SRCS=PY_SRCS
        .ALLOWED=OPTIMIZE_PY_PROTOS NO_OPTIMIZE_PY_PROTOS
        .PEERDIRSELF=CPP_PROTO
        .SEM=IGNORED
        SET(PEERDIR_TAGS PY3 PY3_PROTO)
        ENABLE(PY3_PROTO)
        DISABLE(_NEED_SBOM_INFO)
        OPTIMIZE_PY_PROTOS()
        OBJ_SUF=.py3
        # Can not use NO_LINT(), because is not allowed outside of contrib directory
        SET(_NO_LINT_VALUE none_internal)

        when ($_COMMON_GOOGLE_APIS != "None") {
            PEERDIR += contrib/libs/googleapis-common-protos
        }

        _IGNORE_SELF_PEERS=
        _CPP_PROTO_LIBRARY=${MODDIR}/$_CPP_PROTO_MODULE_PREFIX$REALPRJNAME$_CPP_PROTO_MODULE_SUFFIX
        when ($OPTIMIZE_PY_PROTOS_FLAG == "no") {
            _IGNORE_PEERDIRSELF=CPP_PROTO
        }
        SET_APPEND(_WHOLE_ARCHIVE_LIBS_VALUE_GLOBAL $_CPP_PROTO_LIBRARY)
    }

    module GO_PROTO: GO_LIBRARY {
        .IGNORED=GENERATE_ENUM_SERIALIZATION GENERATE_ENUM_SERIALIZATION_WITH_HEADER YMAPS_SPROTO
        .SEM=IGNORED
        SET(PEERDIR_TAGS GO GO_PROTO)
        ENABLE(GO_PROTO)

        when ($_COMMON_GOOGLE_APIS == "None") {
        }
        elsewhen ($_COMMON_GOOGLE_APIS == "") {
            PEERDIR += $_GO_COMMON_GOOGLE_APIS
            ADDINCL += GLOBAL FOR proto ${ARCADIA_ROOT}/contrib/libs/googleapis-common-protos
        }
        otherwise {
            PEERDIR += $_COMMON_GOOGLE_APIS
            ADDINCL += GLOBAL FOR proto ${ARCADIA_ROOT}/contrib/libs/googleapis-common-protos
        }
    }

    module TS_PROTO: _TS_PROTO_IMPL {
        # opt-in. We don't want to have TS_PROTO by default
        # To include TS_PROTO user have to set INCLUDE_TAGS(TS_PROTO TS_PREPARE_DEPS) in ya.make
        .INCLUDE_TAG=no
        .EPILOGUE=_TS_CONFIG_EPILOGUE
        .PEERDIRSELF=TS_PREPARE_DEPS
        DISABLE(_NEED_SBOM_INFO)
    }

    module TS_PREPARE_DEPS: _PREPARE_DEPS_BASE {
        .INCLUDE_TAG=no
        .IGNORED=PEERDIR
        DISABLE(_NEED_SBOM_INFO)
    }

    module DESC_PROTO: _BARE_UNIT {
        .CMD=_PROTO_DESC_MERGE_CMD
        .SEM=IGNORED
        .EXTS=.desc .rawproto
        .NODE_TYPE=Library
        .IGNORED=GENERATE_ENUM_SERIALIZATION GENERATE_ENUM_SERIALIZATION_WITH_HEADER YMAPS_SPROTO RESOURCE GO_PROTO_PLUGIN GRPC
        .ALIASES=SRCS=_SRCS_NO_GLOBAL

        SET(PEERDIR_TAGS DESC_PROTO)
        ENABLE(DESC_PROTO)
        DISABLE(_NEED_SBOM_INFO)
        MODULE_SUFFIX=.self.protodesc
        SET(MODULE_TYPE LIBRARY)
        SET(_MODDIR_HASH ${hash:MODDIR})

        _EVLOG_CMDLINE=$_PROTO_DESC_CMDLINE
        _PROTO_CMDLINE=$_PROTO_DESC_CMDLINE

        when ($_COMMON_GOOGLE_APIS != "None") {
            PEERDIR += contrib/libs/googleapis-common-protos
        }

        when ($NEED_GOOGLE_PROTO_PEERDIRS == "yes") {
            when ($USE_VANILLA_PROTOC == "yes") {
                PEERDIR += contrib/libs/protobuf_std/builtin_proto/protos_from_protobuf
            }
            otherwise {
                PEERDIR += contrib/libs/protobuf/builtin_proto/protos_from_protoc
            }
        }
    }
}

module PROTO_DESCRIPTIONS: _BARE_UNIT {
    .CMD=_PROTO_DESC_MERGE_PEERS_CMD
    .PEERDIR_POLICY=as_build_from
    .NODE_TYPE=Library
    .RESTRICTED=SRCS
    .FINAL_TARGET=yes

    SET(MODULE_TAG PROTO_DESCRIPTIONS)
    SET(PEERDIR_TAGS DESC_PROTO)
    SET(MODULE_SUFFIX .protodesc)
    SET(MODULE_TYPE PROTO_DESCRIPTIONS)
}

module PROTO_REGISTRY: PROTO_DESCRIPTIONS {
    SET(MODULE_TAG PROTO_REGISTRY)
    SET(MODULE_TYPE PROTO_REGISTRY)
}

macro EVLOG_CMD(SRC) {
    .CMD=$_EVLOG_CMDLINE
    .SEM=$_EVLOG_CMDLINE
}

macro PROTO_CMD(SRC) {
    .CMD=$_PROTO_CMDLINE
    .SEM=$_PROTO_CMDLINE
}

_CPP_EVLOG_CMDLINE=$_CPP_EVLOG_CMD($SRC)
_CPP_PROTO_CMDLINE=$_CPP_PROTO_CMD($SRC)
_CPP_PROTO_EVLOG_CMDLINE=$_CPP_PROTO_EVLOG_CMD($SRC)
_CPP_VANILLA_PROTO_CMDLINE=$_CPP_VANILLA_PROTO_CMD($SRC)
_JAVA_EVLOG_CMDLINE=$_JAVA_EVLOG_CMD($SRC)
_JAVA_PROTO_CMDLINE=$_JAVA_PROTO_CMD($SRC)
_PROTO_DESC_CMDLINE=$_PROTO_DESC_RAWPROTO_CMD($SRC)
_PY_EVLOG_CMDLINE=$_PY_EVLOG_CMD($SRC)
_PY_PROTO_CMDLINE=$_PY_PROTO_CMD($SRC)