macro _INPUT_WITH_FLAG(Flag, IN[]) {
    .CMD=$_INPUT_WITH_FLAG_IMPL(${pre=$Flag :IN} IN $IN)
}

macro _INPUT_WITH_FLAG_IMPL(IN{input}[], Args...) {
    .CMD=$Args ${hide;input:IN}
}

macro ACCELEO(XSD{input}[], MTL{input}[], MTL_ROOT="${MODDIR}", LANG{input}[], OUT{output}[], OUT_NOAUTO{output}[], OUTPUT_INCLUDES[], DEBUG?"stdout2stderr":"stderr2stdout") {
    .PEERDIR=build/platform/java/jdk $JDK_RESOURCE_PEERDIR
    .CMD=${cwd:ARCADIA_BUILD_ROOT} $YMAKE_PYTHON ${input;pre=build/scripts/:DEBUG.py} $JDK_RESOURCE/bin/java -Dfile.encoding=utf8 -classpath ${RUN_JAR_PROG_CP_PRE}${tool:"tools/acceleo"}${RUN_JAR_PROG_CP_SUF} ru.yandex.se.logsng.tool.Cli $_INPUT_WITH_FLAG(--xsd IN $XSD) $_INPUT_WITH_FLAG(--mtl IN $MTL) $_INPUT_WITH_FLAG(--lang IN $LANG) --output-dir $BINDIR --build-root ${ARCADIA_BUILD_ROOT} --source-root ${ARCADIA_ROOT}  --mtl-root $MTL_ROOT ${hide;output_include:OUTPUT_INCLUDES} ${hide;output:OUT} ${hide;noauto;output:OUT_NOAUTO} ${hide;kv:"p JV"} ${hide;kv:"pc light-blue"} ${hide;kv:"show_out"}
}

### @usage: JAVA_LIBRARY()
###
### The module describing java library build.
###
### Documentation: https://wiki.yandex-team.ru/yatool/java/
module JAVA_LIBRARY: JAR_LIBRARY {
    .SEM=_BUILD_JAR_SEM
}

module _JAR_PROGRAM_COMPILATION: JAR_LIBRARY {
    .IGNORED=JAVA_RUNTIME_PEERDIR JAVA_RUNTIME_EXCLUDE
    .ALIASES=JAVA_RUNTIME_PEERDIR=_NOOP_MACRO JAVA_RUNTIME_EXCLUDE=_NOOP_MACRO
    .FINAL_TARGET=no

    when ($OPENSOURCE == "yes" && $AUTOCHECK == "yes") {
        # FIXME: Replace AUTOCHECK == yes with _not a host platform_ check after YMAKE-218
        MODULE_LICENSES_RESTRICTION_TYPES = ALLOW_ONLY
        MODULE_LICENSES_RESTRICTIONS = SERVICE REQUIRE_CITATION REQUIRE_MODIFICATIONS_DISCLOSURE

        when ($MAKE_UBERJAR_VALUE == "yes") {
            # At the time LICENCE_RESTRICTION does not properly distinct static / dynamic linkage in UBERJAR() modules.
            # Hence we forbid using UBERJAR() in OPENSOURCE()
            #
            # Should be fixed in YMAKE-1043
            _OK = no
        }
    }
    when ($OS_IOS == "yes" || $OS_ANDROID == "yes" || $MAPSMOBI_BUILD_TARGET == "yes") {
        MODULE_LICENSES_RESTRICTION_TYPES = ALLOW_ONLY
        MODULE_LICENSES_RESTRICTIONS = SERVICE REQUIRE_CITATION
    }

    ASSERT(_OK "UBERJAR() macro can not be used in this configuration, see YMAKE-1043")
}

### @usage: JAVA_PROGRAM()
###
### The module describing java programs build.
### Output artifacts: .jar and directory with all the jar to the classpath of the formation.
###
### Documentation: https://wiki.yandex-team.ru/yatool/java/
multimodule JAVA_PROGRAM {
    module JAR_RUNNABLE: _JAR_RUNNABLE {
        .ALLOWED=JAVA_RUNTIME_PEERDIR JAVA_RUNTIME_EXCLUDE
        .SEM=_SEM_IGNORED
        # TODO(svidyuk) JAVA_DEPENDENCIES_CONFIGURATION must not be ignored here but there are diagnostics issues in case of ECLUDE in the middle:
        # * A -> B -> C -> lib-v1.4
        #    |    |-> DM(lib-v1.1)
        #    |    |-> EXCLUDE(lib-v1.4)
        #    |    |-> FORBID_CONFLICT_DM_RECENT = OK
        #    |-> DM(lib-v1.1)
        #    |-> FORBID_CONFLICT_DM_RECENT = FAIL (because downgrade from v1.4 to v1.1 is detected before understanding that v1.4 was excuded on the examined path)
        .IGNORED=RUN_JAVA_PROGRAM JAVA_DEPENDENCIES_CONFIGURATION PROVIDES FEATURE_VERSION
        .ALIASES=JAVA_RUNTIME_PEERDIR=PEERDIR JAVA_RUNTIME_EXCLUDE=EXCLUDE
        .PEERDIRSELF=JAR_COMPILATION

        SET(MODULE_TYPE JAVA_PROGRAM)
    }
    module JAR_COMPILATION: _JAR_PROGRAM_COMPILATION {
        .SEM=_BUILD_JAR_SEM
        SET(MODULE_TYPE JAVA_PROGRAM)
    }
}

_PROCESSOR_CLASSES_VALUE=
macro PROCESSOR_CLASSES(Classes...) {
    SET_APPEND(_PROCESSOR_CLASSES_VALUE $Classes)
}

macro AUTO_SERVICE(Ver) {
    USE_ANNOTATION_PROCESSOR(contrib/java/com/google/auto/service/auto-service/${Ver})
    # TODO Remove PEERDIR - old AP mechanic
	PEERDIR(contrib/java/com/google/auto/service/auto-service-annotations/${Ver})
}

_BUILD_JAVA_ANNOTATION_PROCESSOR_SEM=$_BUILD_JAR_SEM

### @usage: JAVA_ANNOTATION_PROCESSOR()
###
### The module describing java annotation processor build.
### Output artifacts: .jar and directory with all the jar to the classpath of the formation.
###
### Documentation: https://wiki.yandex-team.ru/yatool/java/
multimodule JAVA_ANNOTATION_PROCESSOR {
    module JAR_RUNNABLE: _JAR_RUNNABLE {
        .ALLOWED=JAVA_RUNTIME_PEERDIR JAVA_RUNTIME_EXCLUDE
        .SEM=_SEM_IGNORED
        .IGNORED=RUN_JAVA_PROGRAM PROVIDES FEATURE_VERSION
        .ALIASES=JAVA_RUNTIME_PEERDIR=PEERDIR JAVA_RUNTIME_EXCLUDE=EXCLUDE
        .PEERDIRSELF=JAR_COMPILATION

        SET(MODULE_TYPE JAVA_ANNOTATION_PROCESSOR)
    }
    module JAR_COMPILATION: _JAR_PROGRAM_COMPILATION {
        .SEM=_BUILD_JAVA_ANNOTATION_PROCESSOR_SEM
    }
}

_RUN_JAVA_CONTRIB_ANNOTATION_PROCESSOR_SEM=
multimodule JAVA_CONTRIB_ANNOTATION_PROCESSOR {
    module JAR_RUNNABLE: _JAR_RUNNABLE {
        .IGNORED=JAVA_SRCS RUN_JAR_PROGRAM RUN_JAVA_PROGRAM JAR_RESOURCE SRC_RESOURCE LOCAL_JAR
        .PEERDIRSELF=JAR_COMPILATION
        .SEM=_RUN_JAVA_CONTRIB_ANNOTATION_PROCESSOR_SEM

        SET(MODULE_TYPE JAVA_ANNOTATION_PROCESSOR)
        ENABLE(DISABLE_SCRIPTGEN)
    }
    module JAR_COMPILATION: JAVA_CONTRIB {
        .ALIASES=JAVA_RUNTIME_PEERDIR=_NOOP_MACRO JAVA_RUNTIME_EXCLUDE=_NOOP_MACRO
        .FINAL_TARGET=no
        .SEM=_BUILD_JAVA_ANNOTATION_PROCESSOR_SEM
    }
}

### @usage: JUNIT_TESTS_JAR(path/to/some/peer realname.jar)
###
### Specifies jar to search test suites and test cases. By default tests are
### searched in the jar compild by JTEST or JUNIT5 module sources. This macro
### allows to specify diferent jar to search tests.
###
### Only one jar file is used to search tests. If this macro invoked multiple
### times (which is not reccomended practice) only the last invocation will
### have effect.
###
### If this macro is used no test from the module build by current ya.make
### will be searched and executed.
macro JUNIT_TESTS_JAR(Dir, Jar) {
    SET(UNITTEST_DIR $Dir)
    PEERDIR($Dir)
    SET(UNITTEST_MOD $Dir/$Jar)
}

_BUILD_JUNIT5_JAR_SEM=$_BUILD_JAR_SEM && junit5_test

multimodule JUNIT5 {
    # ATTENTION ya ide idea relies on this submodule name to find scope of `ya make` build before project generation
    module JAR_TESTABLE: _JAR_TEST {
        .ALLOWED=YT_SPEC
        # TODO(svidyuk) JAVA_DEPENDENCIES_CONFIGURATION must not be ignored here but there are diagnostics issues in case of ECLUDE in the middle:
        # * A -> B -> C -> lib-v1.4
        #    |    |-> DM(lib-v1.1)
        #    |    |-> EXCLUDE(lib-v1.4)
        #    |    |-> FORBID_CONFLICT_DM_RECENT = OK
        #    |-> DM(lib-v1.1)
        #    |-> FORBID_CONFLICT_DM_RECENT = FAIL (because downgrade from v1.4 to v1.1 is detected before understanding that v1.4 was excuded on the examined path)
        .IGNORED=JAVA_SRCS RUN_JAVA_PROGRAM JAVA_DEPENDENCIES_CONFIGURATION PROVIDES FEATURE_VERSION
        .ALIASES=JAVA_TEST_PEERDIR=PEERDIR JAVA_TEST_EXCLUDE=EXCLUDE
        .PEERDIRSELF=JAR_COMPILATION
        .SEM=_SEM_IGNORED

        PEERDIR(devtools/jtest-annotations/junit5)

        SET(MODULE_TYPE JUNIT5)
    }
    module JAR_COMPILATION: JAR_LIBRARY {
        .ALLOWED=YT_SPEC
        .ALIASES=JAVA_TEST_PEERDIR=_NOOP_MACRO JAVA_TEST_EXCLUDE=_NOOP_MACRO
        .FINAL_TARGET=no
        .DEFAULT_NAME_GENERATOR=FullPath
        .SEM=_BUILD_JUNIT5_JAR_SEM
        .IGNORED=JUNIT_TESTS_JAR

        PEERDIR+=devtools/junit5-runner
        PEERDIR+=build/platform/java/jacoco-agent

        when ($OPENSOURCE != "yes") {
            PEERDIR+=devtools/jtest-annotations/junit5
        }
        SET(MODULE_TYPE JUNIT5)

        when ($OPENSOURCE == "yes" && $AUTOCHECK == "yes") {
            # FIXME: Replace AUTOCHECK == yes with _not a host platform_ check after YMAKE-218
            MODULE_LICENSES_RESTRICTION_TYPES = ALLOW_ONLY
            MODULE_LICENSES_RESTRICTIONS = SERVICE REQUIRE_CITATION REQUIRE_MODIFICATIONS_DISCLOSURE

            when ($MAKE_UBERJAR_VALUE == "yes") {
                # At the time LICENCE_RESTRICTION does not properly distinct static / dynamic linkage in UBERJAR() modules.
                # Hence we forbid using UBERJAR() in OPENSOURCE()
                #
                # Should be fixed in YMAKE-1043
                _OK = no
            }
        }

        ASSERT(_OK "UBERJAR() macro can not be used in this condfiguration, see YMAKE-1043")
    }
}

_BUILD_JUNIT4_JAR_SEM=$_BUILD_JAR_SEM && junit4_test

multimodule JTEST {
    # ATTENTION ya ide idea relies on this submodule name to find scope of `ya make` build before project generation
    module JAR_TESTABLE: _JAR_TEST {
        .ALLOWED=YT_SPEC
        # TODO(svidyuk) JAVA_DEPENDENCIES_CONFIGURATION must not be ignored here but there are diagnostics issues in case of ECLUDE in the middle:
        # * A -> B -> C -> lib-v1.4
        #    |    |-> DM(lib-v1.1)
        #    |    |-> EXCLUDE(lib-v1.4)
        #    |    |-> FORBID_CONFLICT_DM_RECENT = OK
        #    |-> DM(lib-v1.1)
        #    |-> FORBID_CONFLICT_DM_RECENT = FAIL (because downgrade from v1.4 to v1.1 is detected before understanding that v1.4 was excuded on the examined path)
        .IGNORED=JAVA_SRCS RUN_JAVA_PROGRAM JAVA_DEPENDENCIES_CONFIGURATION PROVIDES FEATURE_VERSION
        .ALIASES=JAVA_TEST_PEERDIR=PEERDIR JAVA_TEST_EXCLUDE=EXCLUDE
        .PEERDIRSELF=JAR_COMPILATION
        .SEM=_SEM_IGNORED

        SET(MODULE_TYPE JTEST)
        PEERDIR(devtools/junit-runner devtools/jtest-annotations/junit4)
        DEPENDENCY_MANAGEMENT(contrib/java/com/google/code/gson/gson/2.10.1 contrib/java/com/beust/jcommander/1.72 contrib/java/junit/junit/4.12)
    }
    module JAR_COMPILATION: JAR_LIBRARY {
        .ALLOWED=YT_SPEC
        .ALIASES=JAVA_TEST_PEERDIR=_NOOP_MACRO JAVA_TEST_EXCLUDE=_NOOP_MACRO
        .FINAL_TARGET=no
        .DEFAULT_NAME_GENERATOR=FullPath
        .SEM=_BUILD_JUNIT4_JAR_SEM
        .IGNORED=JUNIT_TESTS_JAR

        SET(MODULE_TYPE JTEST)
        DEPENDS(contrib/java/org/sonarsource/scanner/cli/sonar-scanner-cli/2.8)

        PEERDIR+=build/platform/java/jacoco-agent
        when ($OPENSOURCE != "yes") {
            PEERDIR+=devtools/jtest-annotations/junit4
        }

        when ($OPENSOURCE == "yes" && $AUTOCHECK == "yes") {
            # FIXME: Replace AUTOCHECK == yes with _not a host platform_ check after YMAKE-218
            MODULE_LICENSES_RESTRICTION_TYPES = ALLOW_ONLY
            MODULE_LICENSES_RESTRICTIONS = SERVICE REQUIRE_CITATION REQUIRE_MODIFICATIONS_DISCLOSURE

            when ($MAKE_UBERJAR_VALUE == "yes") {
                # At the time LICENCE_RESTRICTION does not properly distinct static / dynamic linkage in UBERJAR() modules.
                # Hence we forbid using UBERJAR() in OPENSOURCE()
                #
                # Should be fixed in YMAKE-1043
                _OK = no
            }
        }

        ASSERT(_OK "UBERJAR() macro can not be used in this configuration, see YMAKE-1043")
    }
}

multimodule JTEST_FOR {
    # ATTENTION ya ide idea relies on this submodule name to find scope of `ya make` build before project generation
    module JAR_TESTABLE: _JAR_TEST {
        .ALLOWED=YT_SPEC
        # TODO(svidyuk) JAVA_DEPENDENCIES_CONFIGURATION must not be ignored here but there are diagnostics issues in case of ECLUDE in the middle:
        # * A -> B -> C -> lib-v1.4
        #    |    |-> DM(lib-v1.1)
        #    |    |-> EXCLUDE(lib-v1.4)
        #    |    |-> FORBID_CONFLICT_DM_RECENT = OK
        #    |-> DM(lib-v1.1)
        #    |-> FORBID_CONFLICT_DM_RECENT = FAIL (because downgrade from v1.4 to v1.1 is detected before understanding that v1.4 was excuded on the examined path)
        .IGNORED=JAVA_SRCS RUN_JAVA_PROGRAM JAVA_DEPENDENCIES_CONFIGURATION PROVIDES FEATURE_VERSION
        .ALIASES=JAVA_TEST_PEERDIR=PEERDIR JAVA_TEST_EXCLUDE=EXCLUDE
        .RESTRICTED=JUNIT_TESTS_JAR
        .PEERDIRSELF=JAR_COMPILATION
        .SEM=_SEM_IGNORED

        SET(MODULE_TYPE JTEST_FOR)
        PEERDIR(${UNITTEST_DIR} devtools/junit-runner)
        DEPENDENCY_MANAGEMENT(contrib/java/com/google/code/gson/gson/2.8.6 contrib/java/com/beust/jcommander/1.72 contrib/java/junit/junit/4.12)
    }
    module JAR_COMPILATION: JAR_LIBRARY {
        .ALLOWED=YT_SPEC
        .ALIASES=JAVA_TEST_PEERDIR=_NOOP_MACRO JAVA_TEST_EXCLUDE=_NOOP_MACRO
        .FINAL_TARGET=no
        .DEFAULT_NAME_GENERATOR=FullPath
        .SEM=_BUILD_JUNIT4_JAR_SEM
        .RESTRICTED=JUNIT_TESTS_JAR

        SET(MODULE_TYPE JTEST_FOR)
        DEPENDS(contrib/java/org/sonarsource/scanner/cli/sonar-scanner-cli/2.8)
        PEERDIR(devtools/junit-runner build/platform/java/jacoco-agent ${UNITTEST_DIR})
    }
}

multimodule JAVA_CONTRIB_PROGRAM {
    module JAR_RUNNABLE: _JAR_RUNNABLE {
        .IGNORED=JAVA_SRCS RUN_JAR_PROGRAM RUN_JAVA_PROGRAM JAR_RESOURCE SRC_RESOURCE LOCAL_JAR
        .PEERDIRSELF=JAR_COMPILATION
        .SEM=_SEM_IGNORED

        SET(MODULE_TYPE JAVA_PROGRAM)
        ENABLE(DISABLE_SCRIPTGEN)
    }
    module JAR_COMPILATION: JAVA_CONTRIB {
        .ALIASES=JAVA_RUNTIME_PEERDIR=_NOOP_MACRO JAVA_RUNTIME_EXCLUDE=_NOOP_MACRO
        .FINAL_TARGET=no
        .SEM=_BUILD_JAR_SEM

        SET(MODULE_TYPE JAVA_PROGRAM)
    }
}

# tag:java-specific
JAVA_VCS_MF_ARG=
COMPILE_JAVA_MF=${hide:JAVA_FAKEID} $COMPILE_JAVA $MAVEN_EXPORT_CMD

# tag:java-specific
when ($EXT_JAVA_VCS_INFO == "yes") {
    JAVA_VCS_MF_ARG=--vcs-mf $VCS_JAVA
    COMPILE_JAVA_MF=${hide:JAVA_FAKEID} $GENERATE_VCS_JAVA_INFO_NODEP && $COMPILE_JAVA $MAVEN_EXPORT_CMD
}

# tag:java-specific
EXT_JAVA_VCS_INFO=no
### @usage: EMBED_JAVA_VCS_INFO()
###
### Embed manifest with vcs info into `EXTERNAL_JAVA_LIBRARY`
### By default this is disabled.
macro EMBED_JAVA_VCS_INFO() {
    .SEM=add_vcs_info_to_mf ${hide;output:"VcsInfoMfDummy.java"}
    ENABLE(EXT_JAVA_VCS_INFO)
}

# tag:java-specific tag:internal
### @usage: EXTERNAL_JAVA_LIBRARY() #internal
###
### EXTERNAL_JAVA_LIBRARY() is a module for creating a .jar file using non-Java code (generators etc.)
### Unlike regular JAVA_LIBRARY this module doesn't produce .pom file, so it cannot be exported to Maven itself.
### PEERDIR it from JAVA_LIBRARY or JAVA_PROGRAM for export to Maven.
module EXTERNAL_JAVA_LIBRARY: _BASE_UNIT {
    .EXTS=.jsrc .java .jar .mf
    .NODE_TYPE=Bundle
    .CMD=COMPILE_JAVA_MF
    # TODO(YMAKE-27) all contribs involved into opensource export must be JAVA_CONTRIB modules
    # and this module must not be intended for export. Such hange will break JBUILD and thus is
    # blocked on YMAKE-27
    .SEM=_JAVA_CONTRIB_SEM
    .PEERDIR_POLICY=as_build_from
    .FINAL_TARGET=no
    .ALIASES=SRCS=_SRCS_NO_GLOBAL
    .ALLOWED=EMBED_JAVA_VCS_INFO
    .RESTRICTED=EXTERNAL_JAR
    .GLOBAL=MAVEN_EXPORT_COORDS

    SET(MODULE_TAG JAVA)

    PEERDIR(build/platform/java/jdk)
    PEERDIR+=$JDK_RESOURCE_PEERDIR $EXTERNAL_JAVA_EXTRA_PEERDIR
    when ($KOTLIN_PROTO == "yes") {
        PEERDIR+=build/platform/java/kotlin contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk8/${_KOTLIN_VERSION}
    }

    when ($MAVEN_EXPORT == "yes") {
        when ($MAVEN_DEPLOY == "yes") {
            PEERDIR+=build/external_resources/maven
            MAVEN_EXPORT_CMD= && $MAVEN_EXPORT_GEN_DEPLST && $MAVEN_EXPORT_GEN_POM && $MAVEN_DEPLOY_CMD
        }
        otherwise {
            MAVEN_EXPORT_CMD= && $MAVEN_EXPORT_GEN_DEPLST && $MAVEN_EXPORT_GEN_POM
        }
        MAVEN_EXPORT_COORDS_GLOBAL=$MAVEN_EXPORT_GROUP_ID:${MODULE_PREFIX}${REALPRJNAME}:${MAVEN_EXPORT_VERSION}:
    }

    PEERDIR_TAGS=JAVA JAVA_PROTO JAVA_PROTO_FROM_SCHEMA JAVA_FBS JAVA_IDL PACKAGE_UNION
    HAS_MANAGEABLE_PEERS=yes
    DYNAMIC_LINK=yes
    _PROTO_CMDLINE=$_JAVA_PROTO_CMDLINE
    _EVLOG_CMDLINE=$_JAVA_EVLOG_CMDLINE
    _FBS_CMDLINE=$_JAVA_FLATC_CMDLINE

    when ($PACKAGE_PREFIX) {
        PACKAGE_PREFIX_ARGS=--package-prefix=$PACKAGE_PREFIX
    }

    DISABLE(NEED_PLATFORM_PEERDIRS)
    NO_PLATFORM()
    SET(MODULE_SUFFIX .jar)
    SET(MODULE_LANG JAVA)

    _WHEN_EXPORT_GRADLE()
}

# tag:java-specific
ALL_JAR_SOURCES=
LINT_JAVA_SOURCES=
ALL_SRCDIRS=
LINK_JAR_RESOURCES=
LINK_JAR_JSOURCES=
JAR_GEN_SRCS=
JAR_GEN_JSRCS=
macro _JAVA_SRCS(RESOURCES?"yes":"no", SRCDIR=".", PACKAGE_PREFIX="", EXCLUDE[], FILES[], SKIP_CHECK_SRCDIR?"SKIP_CHECK_SRCDIR":"", Globs...) {
    _CHECK_JAVA_SRCDIR($SKIP_CHECK_SRCDIR $SRCDIR)
    SET_APPEND(ALL_SRCDIRS $SRCDIR)
    SET(VAR_SALT $SRCDIR $Globs $EXCLUDE $PACKAGE_PREFIX $RESOURCES $FILES)
    SET(JAR_SRCS_GLOB uniq_${hash:VAR_SALT})
    _LATE_GLOB(${JAR_SRCS_GLOB} ${pre=${SRCDIR}/:Globs} EXCLUDE ${EXCLUDE})
    SET_APPEND(LINT_JAVA_SOURCES \${rootrel;input;ext=.java:${JAR_SRCS_GLOB}})
    SET_APPEND(ALL_JAR_SOURCES --jsources ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.src.txt --resources ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.res.txt --srcdir ${quo:SRCDIR} \${input:${JAR_SRCS_GLOB}} ${pre=\$\{input\:\";suf=\"\}:FILES})
    _FILL_JAR_COPY_RESOURCES_CMD(LINK_JAR_RESOURCES ${quo:SRCDIR} ${BINDIR}/cls ${PACKAGE_PREFIX} ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.res.txt)
    _FILL_JAR_COPY_RESOURCES_CMD(LINK_JAR_JSOURCES ${quo:SRCDIR} ${BINDIR}/src ${PACKAGE_PREFIX} ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.src.txt)
    _FILL_JAR_GEN_SRCS(JAR_GEN_SRCS  JAR     $SRCDIR ${BINDIR}/cls ${BINDIR}/all-java.srclst $KT_SRCLIST ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.res.txt $Globs EXCLUDE $EXCLUDE)
    _FILL_JAR_GEN_SRCS(JAR_GEN_JSRCS SRC_JAR $SRCDIR ${BINDIR}/cls ${BINDIR}/all-java.srclst $KT_SRCLIST ${BINDIR}/misc/${tolower:JAR_SRCS_GLOB}.src.txt $Globs EXCLUDE $EXCLUDE)
}

# tag:java-specific
# Fill semantic jar_source_set by JAVA_SRCS() Args
_JAR_SOURCE_SET_SEM=
macro _SEM_JAR_SOURCE_SET(SRCDIR=".", PACKAGE_PREFIX="", EXCLUDE[], FILES[], RESOURCES?"RESOURCES":"", SKIP_CHECK_SRCDIR?"SKIP_CHECK_SRCDIR":"", Globs...) {
    # Now ignore SKIP_CHECK_SRCDIR, PACKAGE_PREFIX, EXCLUDE, RESOURCES, FILES
    SET_APPEND(_JAR_SOURCE_SET_SEM && jar_source_set ${pre=${SRCDIR}\::Globs})
}

### Fill JAVA_SRCS to value for ya ide idea and real apply for late globs
macro FULL_JAVA_SRCS(Args...) {
    _IDEA_JAVA_SRCS_VALUE($Args)
    _JAVA_SRCS($Args)
    _SEM_JAR_SOURCE_SET($Args)
}

# tag:java-specific
### @usage: DEFAULT_JAVA_SRCS_LAYOUT()
###
### DEFAULT_JAVA_SRCS_LAYOUT() declare all source files can be find at maven/gradle standard path src/main/java **/*.java
### and all resources an be find at maven/gradle standard path src/main/resources **/*
macro DEFAULT_JAVA_SRCS_LAYOUT() {
    # Maven default source paths, supported by gradle too
    # JAVA_SRCS may be alias of FULL_JAVA_SRCS
    FULL_JAVA_SRCS(SRCDIR src/main/java **/*.java SKIP_CHECK_SRCDIR)
    FULL_JAVA_SRCS(RESOURCES SRCDIR src/main/resources **/* SKIP_CHECK_SRCDIR)
}

# tag:java-specific
### @usage: DEFAULT_JUNIT_JAVA_SRCS_LAYOUT()
###
### DEFAULT_JUNIT_JAVA_SRCS_LAYOUT() declare all test source files can be find at maven/gradle standard path src/test/java **/*.java
### and all resources can be find at maven/gradle standard path src/test/resources **/*
macro DEFAULT_JUNIT_JAVA_SRCS_LAYOUT() {
    # Maven default test source paths, supported by gradle too
    # JAVA_SRCS may be alias of FULL_JAVA_SRCS
    FULL_JAVA_SRCS(SRCDIR java **/*.java SKIP_CHECK_SRCDIR)
    FULL_JAVA_SRCS(RESOURCES SRCDIR resources **/* SKIP_CHECK_SRCDIR)
}

macro _HASH_HELPER(Args...) {
    .CMD=${hash:Args}
    .SEM=${hash:Args}
}

macro _HASH_GENTAR_HELPER(HASH, OUT_DIR[]) {
    .CMD=${cwd:BINDIR} $YMAKE_PYTHON ${input:"build/scripts/autotar_gendirs.py"} --pack ${OUT_DIR} --outs ${output;tared;suf=.$HASH.gentar:OUT_DIR} ${hide;kv:"tared_kind nodir"}
    .SEM=${hide;output;tared;suf=.$HASH.gentar:OUT_DIR}
}

macro _GENTAR_HELPER(OUT_DIR[], Args...) {
    .CMD=$_HASH_GENTAR_HELPER(${hash:Args} OUT_DIR $OUT_DIR)
    .SEM=$_HASH_GENTAR_HELPER(${hash:Args} OUT_DIR $OUT_DIR)
}

# tag:java-specific
RUN_JAR_PROG_CP_PRE=@
RUN_JAR_PROG_CP_SUF=.cplst
when($JDK_VERSION == "8") {
    RUN_JAR_PROG_CP_PRE=
    RUN_JAR_PROG_CP_SUF=
}

# tag:java-specific
JDK_LATEST_VERSION=23
JDK_LATEST_PEERDIR=build/platform/java/jdk/jdk${JDK_LATEST_VERSION}

# tag:java-specific
# Fill semantic by RUN_JAVA_PROGRAM()
_SEM_RUN_JAVA_PROGRAM=runs-ITEM \
    && runs-args ${Args} \
    && runs-classpath ${RUN_JAR_PROG_CP_PRE}${tool:CLASSPATH}${RUN_JAR_PROG_CP_SUF} \
    && runs-cwd ${CWD} ${hide;cwd:CWD} \
    && runs-in ${IN} ${hide;input:IN} \
    && runs-in_dir ${IN_DIR} \
    && runs-in_dirs_inputs ${IN_DIRS_INPUTS} \
    && runs-in_noparse ${IN_NOPARSE} ${hide;context=TEXT;input:IN_NOPARSE} \
    && runs-out ${OUT} ${hide;output:OUT} ${OUT_NOAUTO} ${hide;noauto;output:OUT_NOAUTO} \
    $_GENTAR_HELPER($CLASSPATH $IN_DIR $IN $IN_NOPARSE $TOOL $Args OUT_DIR $OUT_DIR) \
    && runs-out_dir ${OUT_DIR} \
    && runs-tool ${TOOL} ${hide;tool:TOOL}

macro _DO_2_RUN_JAR_PROGRAM(IN_DIRS_VAR="uniq_", IN_DIRS_INPUTS[], IN{input}[], IN_NOPARSE{input}[], IN_DIR[], OUT_NOAUTO{output}[], OUT{output}[], TOOL{tool}[], OUT_DIR[], CLASSPATH[], ADD_SRCS_TO_CLASSPATH?"yes":"no", CWD="${ARCADIA_BUILD_ROOT}", STDOUT="", STDOUT_NOAUTO="", Args...) {
    _LATE_GLOB(${IN_DIRS_VAR} ${suf=/**/*:IN_DIR})
    _CHECK_RUN_JAVA_PROG_CLASSPATH($CLASSPATH)
    .PEERDIR=build/platform/java/jdk $JDK_RESOURCE_PEERDIR
    .CMD=${hide;kv:"p RJ"} ${hide;kv:"pc blue"} ${hide:JAVA_FAKEID} ${cwd:BINDIR} $YMAKE_PYTHON ${input:"build/scripts/mkdir.py"} ${OUT_DIR} && ${cwd:CWD} $YMAKE_PYTHON ${input:"build/scripts/setup_java_tmpdir.py"} $YMAKE_PYTHON ${input:"build/scripts/stdout2stderr.py"} ${pre=--file=:STDOUT} ${hide;output:STDOUT} ${pre=--file=:STDOUT_NOAUTO} ${hide;noauto;output:STDOUT_NOAUTO} $YMAKE_PYTHON ${input:"build/scripts/fix_java_command_file_cp.py"} --build-root ${ARCADIA_BUILD_ROOT} $JDK_RESOURCE/bin/java -Dfile.encoding=utf8 -classpath ${RUN_JAR_PROG_CP_PRE}${tool:CLASSPATH}${RUN_JAR_PROG_CP_SUF} ${Args} && $_GENTAR_HELPER($CLASSPATH $IN_DIR $IN $IN_NOPARSE $TOOL $Args OUT_DIR $OUT_DIR) ${hide;input:IN} ${hide;context=TEXT;input:IN_NOPARSE} ${hide;noauto;output:OUT_NOAUTO} ${hide;output:OUT} ${hide;tool:TOOL} ${IN_DIRS_INPUTS}
    .SEM=$_SEM_RUN_JAVA_PROGRAM
}

# tag:java-specific
macro _DO_1_RUN_JAR_PROGRAM(IN_DIRS_VAR="uniq", Args...) {
    _DO_2_RUN_JAR_PROGRAM($Args IN_DIRS_VAR $IN_DIRS_VAR IN_DIRS_INPUTS ${"$"}{hide;input:$IN_DIRS_VAR})
}

# tag:java-specific
macro RUN_JAVA_PROGRAM(Args...) {
    _DO_1_RUN_JAR_PROGRAM($Args IN_DIRS_VAR uniq_${hash:Args})
}

# tag:java-specific
_JAR_ANN_PROCESSORS=
_JAR_ANN_PROC_OPT_PREFIX=
_ANN_PROCESSORS_SEM=
macro JAR_ANNOTATION_PROCESSOR(Classes...) {
    SET_APPEND(_JAR_ANN_PROCESSORS $Classes)
    SET(_JAR_ANN_PROC_OPT_PREFIX -processor)
    SET_APPEND(_ANN_PROCESSORS_SEM && annotation_processors $Classes)

    # for ya ide idea only
    SET_APPEND(ANNOTATION_PROCESSOR_VALUE $ARGS_DELIM $Classes)
}

# tag:java-specific
macro _JAR_ANN_PROC_OPTS(Classes...) {
    .CMD=$_JAR_ANN_PROC_OPT_PREFIX ${join=,:Classes} $_USE_ANNOTATION_PROCESSOR_OPT
}

# tag:java-specific
_USE_ANNOTATION_PROCESSOR_PATH=
_USE_ANNOTATION_PROCESSOR_OPT=
_USE_ANNOTATION_PROCESSOR_SEM=
### @usage: USE_ANNOTATION_PROCESSOR(Path)
###
### Used to specify annotation processor for building JAVA_PROGRAM() and JAVA_LIBRARY().
macro USE_ANNOTATION_PROCESSOR(Path) {
    SET(_USE_ANNOTATION_PROCESSOR_PATH $Path)
}

when ($_USE_ANNOTATION_PROCESSOR_PATH != "") {
    _USE_ANNOTATION_PROCESSOR_TOOL = ${tool:_USE_ANNOTATION_PROCESSOR_PATH}
    _USE_ANNOTATION_PROCESSOR_OPT += ${pre=-processorpath "@";suf=.cplst:_USE_ANNOTATION_PROCESSOR_TOOL}
    _USE_ANNOTATION_PROCESSOR_SEM += && use_annotation_processor $_USE_ANNOTATION_PROCESSOR_PATH/${nopath:_USE_ANNOTATION_PROCESSOR_TOOL}
}

# tag:java-specific
macro _NOOP_MACRO(Args...) {
    ENABLE(UNUSED_MACRO)
}

# tag:java-specific
module _JAR_BASE: _BARE_UNIT {
    .NODE_TYPE=Bundle
    .CMD=TOUCH_UNIT
    .PEERDIR_POLICY=as_build_from
    .FINAL_TARGET=no
    .ALIASES=SRCS=_SRCS_NO_GLOBAL
    .ALLOWED=EMBED_JAVA_VCS_INFO DEPENDENCY_MANAGEMENT EXCLUDE
    .DEFAULT_NAME_GENERATOR=TwoDirNames
    .RESTRICTED=WITH_JDK RESOURCE RESOURCE_FILES
    # TODO: GENERAGTE_SCRIPT have nothing to do outside of JAVA_PROGRAM runable submodule it must be RESTRICTED rather then IGNORED
    .IGNORED=GENERATE_SCRIPT

    SET(MODULE_TAG JAVA)

    PEERDIR_TAGS=JAVA JAVA_PROTO JAVA_PROTO_FROM_SCHEMA JAVA_FBS JAVA_IDL DLL JAR_COMPILATION __EMPTY__ RESOURCE_LIB

    HAS_MANAGEABLE_PEERS=yes
    DYNAMIC_LINK=yes
    _PROTO_CMDLINE=$_JAVA_PROTO_CMDLINE
    _EVLOG_CMDLINE=$_JAVA_EVLOG_CMDLINE
    _FBS_CMDLINE=$_JAVA_FLATC_CMDLINE

    DISABLE(NEED_PLATFORM_PEERDIRS)
    NO_PLATFORM()
    VCS_JAVA=${suf=.__vcs_version__.mf:TARGET}
    SET(MODULE_LANG JAVA)

    _WHEN_EXPORT_GRADLE()
}

# tag:java-specific
module JAVA_CONTRIB_PROXY: _JAR_BASE {
    .SEM=_SEM_IGNORED
    .VERSION_PROXY=yes

    _DONT_REQUIRE_LICENSE()
    WITHOUT_VERSION()
}

# tag:java-specific
macro _FETCH_CONTRIB(Id, Out, SBR="sbr:") {
    .CMD=${hide:SANDBOX_FAKEID} ${cwd:BINDIR} ${resource;pre=$SBR:Id} $YMAKE_PYTHON ${input:"build/scripts/fetch_from_sandbox.py"} --resource-file $(RESOURCE_ROOT)/sbr/$Id/resource --resource-id $Id --copy-to ${output:Out} ${hide;input:"build/scripts/fetch_from.py"} ${hide;requirements:"network:full"} ${hide;kv:"p SB"} ${hide;kv:"pc yellow"} ${hide;kv:"show_out"}
    ADD_CHECK(check.resource $Id)
}

# tag:java-specific
LOCAL_JAR_PATH=
LOCAL_SOURCES_JAR_PATH=
JAR_RESOURCE_ID=
SRC_RESOURCE_ID=
FETCH_SRCS_JAR=
FETCH_TARGET_JAR=
FETCH_CONTRIB_JAR=${hide:JAVA_FAKEID} $FETCH_TARGET_JAR $FETCH_SRCS_JAR

# tag:java-specific
macro JAR_RESOURCE(Id) {
    SET(JAR_RESOURCE_ID $Id)
}

# tag:java-specific
macro SRC_RESOURCE(Id) {
    SET(SRC_RESOURCE_ID $Id)
}

# tag:java-specific
macro LOCAL_JAR(File) {
    SET(LOCAL_JAR_PATH $File)
}

# tag:java-specific
macro LOCAL_SOURCES_JAR(File) {
    SET(LOCAL_SOURCES_JAR_PATH $File)
}

_JAVA_CONTRIB_SEM= \
    ${hide:TARGET} ${hide:AUTO_INPUT} \
    consumer-classpath $EXPORT_GRADLE_CLASSPATH \
    && consumer-jar ${MODDIR}/${REALPRJNAME}.jar \
    && consumer-type contrib \
    $_JAVAC_SEM \
    && IGNORED

# tag:java-specific
module JAVA_CONTRIB: _JAR_BASE {
    .CMD=FETCH_CONTRIB_JAR
    .PEERDIR_POLICY=as_include
    .SEM=_JAVA_CONTRIB_SEM
    .FINAL_TARGET=yes
    .GLOBAL=MAVEN_EXPORT_COORDS

    when ($JAR_RESOURCE_ID) {
        FETCH_TARGET_JAR= && $_FETCH_CONTRIB($JAR_RESOURCE_ID ${BINDIR}/${MODULE_PREFIX}${REALPRJNAME}${MODULE_SUFFIX})
    }
    otherwise {
        when ($LOCAL_JAR_PATH) {
            FETCH_TARGET_JAR= && $FS_TOOLS copy ${input:LOCAL_JAR_PATH} $TARGET
        }
        otherwise {
            FETCH_TARGET_JAR= && $GENERATE_VCS_JAVA_INFO_NODEP && ${cwd:BINDIR} $JDK_RESOURCE/bin/jar cfvm $TARGET $VCS_JAVA .
            PEERDIR+=build/platform/java/jdk
            PEERDIR+=$JDK_RESOURCE_PEERDIR
        }
    }
    when ($SRC_RESOURCE_ID) {
        FETCH_SRCS_JAR= && $_FETCH_CONTRIB($SRC_RESOURCE_ID ${BINDIR}/${REALPRJNAME}-sources.jar)
    }
    otherwise {
        when ($LOCAL_SOURCES_JAR_PATH) {
            FETCH_SRCS_JAR= && $FS_TOOLS copy ${input:LOCAL_SOURCES_JAR_PATH} ${output;pre=${BINDIR}/;suf=-sources.jar:REALPRJNAME}
        }
        otherwise {
            FETCH_SRCS_JAR= && $GENERATE_VCS_JAVA_INFO_NODEP && $FS_TOOLS md ${BINDIR}/fake-src && ${cwd;suf=/fake-src:BINDIR} $JDK_RESOURCE/bin/jar cfvm ${output;pre=${BINDIR}/;suf=-sources.jar:REALPRJNAME} $VCS_JAVA .
            PEERDIR+=build/platform/java/jdk
            PEERDIR+=$JDK_RESOURCE_PEERDIR
        }
    }
    when ($MAVEN_EXPORT == "yes") {
        _MAKEFILE_INCLUDE_LIKE_DEPS+=pom.xml
        FETCH_CONTRIB_JAR+= && $MAVEN_EXPORT_GEN_DEPLST
    }

    SET(MODULE_SUFFIX .jar)
    _SETUP_MAVEN_EXPORT_COORDS_IF_NEED($MODDIR)
}

MAKE_JAVA_CLASSPATH_FILE=$YMAKE_PYTHON ${input:"build/scripts/make_java_classpath_file.py"} ${hide;input:"build/scripts/process_command_files.py"}

# tag:kotlin-specific
KOTLINC_OPTS_VALUE=

# tag:kotlin-specific
KT_SRCLIST=${BINDIR}/misc/all-kt-sources.txt
KT_SRSCLIST_FLAG=--kotlin $KT_SRCLIST
KT_CLASSES_DIR=${BINDIR}/kt_cls
KT_CLASSPATH=${BINDIR}/kt_cp.txt
COLLECT_KT_CLASSPATH=${WRITER_PY} --file ${BINDIR}/kt_bfg.txt -m --ya-start-command-file ${ext=.jar:MANAGED_PEERS_CLOSURE} --ya-end-command-file
LINK_KT_CLASSPATH=${MAKE_JAVA_CLASSPATH_FILE} ${BINDIR}/kt_bfg.txt $KT_CLASSPATH && $FS_TOOLS md $KT_CLASSES_DIR
COMPILE_KT= \
    ${cwd:ARCADIA_BUILD_ROOT} ${env:"LC_ALL=en_US.UTF-8"} $YMAKE_PYTHON ${input:"build/scripts/run_javac.py"} \
    ${hide;input:"build/scripts/build_java_with_error_prone2.py"} \
    ${hide;input:"build/scripts/setup_java_tmpdir.py"} \
    --kotlin --sources-list $KT_SRCLIST \
    $JDK_RESOURCE/bin/java -jar $KOTLIN_COMPILER_RESOURCE_GLOBAL/kotlin-compiler.jar -no-stdlib -module-name $REALPRJNAME \
    -jvm-target ${KOTLIN_JVM_TARGET} @$KT_SRCLIST -classpath @$KT_CLASSPATH $KOTLINC_FLAGS_VALUE -d $KT_CLASSES_DIR $KOTLINC_OPTS_VALUE
ALL_KT_COMMANDS=
KT_CLASSPATH_ITEM=

# tag:kotlin-specific
KT_KAPT_SOURCES_DIR=${BINDIR}/kapt_gen_src
KT_KAPT_STUBS_DIR=${BINDIR}/kapt_gen_stubs
KT_KAPT_AP_CLASSPATH=
KT_KAPT_PLUGIN_OPTS=-P plugin:org.jetbrains.kotlin.kapt3:sources=${KT_KAPT_SOURCES_DIR} -P plugin:org.jetbrains.kotlin.kapt3:classes=${KT_CLASSES_DIR} -P plugin:org.jetbrains.kotlin.kapt3:stubs=${KT_KAPT_STUBS_DIR} -P plugin:org.jetbrains.kotlin.kapt3:aptMode=stubsAndApt
### @usage: KAPT_OPTS(opts...)
###
### Used to specify annotation processor qualified class names.
### If specified multiple times, only last specification is used.
macro KAPT_OPTS(Args...) {
    SET_APPEND(KT_KAPT_PLUGIN_OPTS ${pre=-P :Args})
}
### @usage: KAPT_ANNOTATION_PROCESSOR(processors...)
###
### Used to specify annotation processor qualified class names.
### If specified multiple times, only last specification is used.
macro KAPT_ANNOTATION_PROCESSOR(Args...) {
    KAPT_OPTS(${pre="plugin:org.jetbrains.kotlin.kapt3:processors=":Args})
}
### @usage: KAPT_ANNOTATION_PROCESSOR_CLASSPATH(jars...)
###
### Used to specify classpath for annotation processors.
### If specified multiple times, all specifications are used.
macro KAPT_ANNOTATION_PROCESSOR_CLASSPATH(Args...) {
    PEERDIR($Args)
    SET_APPEND(KT_KAPT_AP_CLASSPATH $Args)
}

# tag:java-specific
JAVAC_CMD=$JDK_RESOURCE/bin/javac
RUN_JAVAC_ARGS=

# tag:java-specific tag:codenav
JAVA_YNDEXING=no

# tag:java-specific
when ($USE_SYSTEM_KYTHE) {
    KYTHE_RESOURCE=$USE_SYSTEM_KYTHE
}
otherwise {
    KYTHE_RESOURCE=$KYTHE_RESOURCE_GLOBAL
}

# tag:java-specific tag:codenav
_JAVA_YNDEXING_CMD=$YMAKE_PYTHON ${input:"build/scripts/build_java_codenav_index.py"} $TARGET $ARCADIA_BUILD_ROOT $ARCADIA_ROOT ${BINDIR}/all-java.srclst $JDK_RESOURCE/bin/java -jar $KYTHE_RESOURCE/kythe/extractors/javac_extractor.jar
_DO_JAVA_YNDEXING=

# tag:java-specific
SOURCES_JAR=no
when ($BUILD_TYPE == "DEBUG" && $NO_DEBUGINFO != "yes") {
    SOURCES_JAR=yes
}

_PACK_SRC_JAR_IMPL=\
    && $FS_TOOLS md ${BINDIR}/src \
    && $JAR_GEN_JSRCS \
    && $LINK_JAR_JSOURCES \
    && ${cwd;suf=/src:BINDIR} $JDK_RESOURCE/bin/jar cfvm ${output;pre=${BINDIR}/${MODULE_PREFIX};suf=-sources.jar:REALPRJNAME} $VCS_JAVA .
_PACK_SRC_JAR=

# tag:java-specific
_PACK_JNI=
_PACK_JNI_CMD= && $FS_TOOLS link_or_copy_to_dir --ya-start-command-file ${ext=.so:MANAGED_PEERS_CLOSURE} ${ext=.dll:MANAGED_PEERS_CLOSURE} ${ext=.dylib:MANAGED_PEERS_CLOSURE} --ya-end-command-file ${BINDIR}/cls

# tag:java-specific
_MAKE_JSTYLE_FILE_LIST=

# tag:java-specific
_LINK_UBERJAR=
_UBERJAR_SELF=
_DO_LINK_UBERJAR= && $JDK_RESOURCE/bin/java -cp $UBERJAR_RESOURCE/devtools-java_shader.jar ru.yandex.devtools.emigrante.Main --out-jar $TARGET $_UBERJAR_SELF ${pre=--jar ;ext=.jar:MANAGED_PEERS_CLOSURE} ${UBERJAR_PREFIX_FLAG} ${UBERJAR_HIDE_EXCLUDE_FLAGS} ${UBERJAR_HIDE_INCLUDE_FLAGS} $UBERJAR_PATH_EXCLUDES ${UBERJAR_MANIFEST_TRANSFORMER_MAIN_FLAG} ${UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE_FLAGS} ${UBERJAR_APPENDING_TRANSFORMER_FLAGS} ${UBERJAR_SERVICES_RESOURCE_TRANSFORMER_FLAG} \
                  && $YMAKE_PYTHON ${input:"build/scripts/mkdir.py"} $BINDIR/_empty/META-INF \
                  && $YMAKE_PYTHON ${input:"build/scripts/touch.py"} $BINDIR/_empty/META-INF/MANIFEST.MF \
                  && $UPDATE_VCS_JAVA_INFO_NODEP($TARGET) \
                  && ${cwd;suf=/_empty:BINDIR} ${JDK_RESOURCE}/bin/jar ufv ${TARGET} META-INF/MANIFEST.MF \
                  && $JDK_RESOURCE/bin/jar ufvm $TARGET $VCS_JAVA

# tag:java-specific
macro _PACK_JAR_HELPER(Out) {
    .CMD=${cwd;suf=/cls:BINDIR} ${env:"LC_ALL=en_US.UTF-8"} $JDK_RESOURCE/bin/jar cfvm $Out $VCS_JAVA .
}

# tag:java-specific
macro _JAVAC_RUN_HELPER(JAVAC_CMD_WITH_ARGS...) {
    .CMD=${cwd:ARCADIA_BUILD_ROOT} ${env:"LC_ALL=en_US.UTF-8"} $YMAKE_PYTHON ${input:"build/scripts/run_javac.py"} ${hide;input:"build/scripts/build_java_with_error_prone2.py"} ${hide;input:"build/scripts/setup_java_tmpdir.py"} --with-setup-java-tmpdir --sources-list ${BINDIR}/all-java.srclst ${RUN_JAVAC_ARGS} ${JAVAC_CMD_WITH_ARGS} @${BINDIR}/all-java.srclst -classpath ${ARCADIA_BUILD_ROOT}/bfg.jar -Xpkginfo:always ${JAVAC_OPTS} $_JAR_ANN_PROC_OPTS($_JAR_ANN_PROCESSORS) -d ${BINDIR}/cls -g -encoding UTF-8
}

# tag:java-specific
ERROR_PRONE_JDK16PLUS_ADD_OPENS=-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
ERROR_PRONE_2_7_1_FORCED_OPTS=-Xep:InlineMeInliner:OFF -Xep:SameNameButDifferent:OFF

# tag:java-specific
macro _ADD_OPTS_IF_NON_EMPTY(Opt, Args...) {
    .CMD=${pre=$Opt :Args}
}
macro _ADD_GEN_POM_FROM_COORD_FILES_ARGS(Deps...) {
    .CMD=${pre=--deps-coords ;ext=.jar;suf=.mvn_coords:Deps}
}

MAVEN_BIN=$MAVEN_RESOURCE_GLOBAL/bin/mvn

MAVEN_EXPORT_OUT_DIR_FLAG=$_ADD_OPTS_IF_NON_EMPTY(--output-dir ${MAVEN_EXPORT_OUT_DIR})
MAVEN_EXPORT_SOURCE_DIRS=$_ADD_OPTS_IF_NON_EMPTY(--source-dirs ${ALL_SRCDIRS})
MAVEN_EXPORT_DEPS_COORS=$_ADD_GEN_POM_FROM_COORD_FILES_ARGS(${MANAGED_PEERS_CLOSURE})
MAVEN_EXPORT_OUT_DIR=

MAVEN_EXPORT=no
MAVEN_DEPLOY=no
MAVEN_DEPLOY_SOURCES=
MAVEN_EXPORT_VERSION={vcs_revision}
MAVEN_EXPORT_GEN_DEPLST= \
    $WRITER_PY \
    --file ${output;pre=$MODULE_PREFIX;suf=$MODULE_SUFFIX.mvn_coords:REALPRJNAME} \
    --ya-start-command-file -m ${pre=D=:MAVEN_EXPORT_COORDS_GLOBAL} ${pre=E=:EXCLUDED_MAVEN_EXPORT_COORDS_GLOBAL} --ya-end-command-file \
    ${hide:APPLIED_EXCLUDES}
MAVEN_EXPORT_GEN_POM=${hide;kv:"mvn_export yes"} \
    $YMAKE_PYTHON ${input:"build/scripts/generate_pom.py"} \
    --from-coord-files \
    --vcs-info $(VCS)/vcs.json \
    --target-path $MODDIR \
    $MAVEN_EXPORT_SOURCE_DIRS \
    $MAVEN_EXPORT_DEPS_COORS \
    $MAVEN_EXPORT_OUT_DIR_FLAG \
    --target-coords ${suf=.mvn_coords:TARGET} \
    --pom-path ${output:"pom.xml"}

MAVEN_DEPLOY_CMD=$YMAKE_PYTHON ${input:"build/scripts/stdout2stderr.py"} $MAVEN_BIN \
    deploy:deploy-file -DpomFile=$BINDIR/pom.xml \
    -Dfile=$TARGET -DrepositoryId=$MAVEN_REPO_ID -Durl=$MAVEN_REPO_URL -Djava.net.preferIPv4Addresses=false -Djava.net.preferIPv6Addresses=true \
    ${MAVEN_DEPLOY_SOURCES} \
    $_ADD_OPTS_IF_NON_EMPTY(-gs $MAVEN_EXPORT_SETTINGS) \
    $_ADD_OPTS_IF_NON_EMPTY(-s $MAVEN_EXPORT_SETTINGS)
MAVEN_EXPORT_CMD=

# tag:java-specific
JAVA_COVERAGE_SRCLIST_FLAG=--coverage ${output;pre=${MODULE_PREFIX};suf=.cpsf:REALPRJNAME} --source-root ${ARCADIA_ROOT}
JAVA_COVERAGE_SRCLIST=
PREPARE_JAR_BUILD=${cwd:BINDIR} ${YMAKE_PYTHON3} ${input:"build/scripts/prepare_jar_build.py"} \
    --bindir ${BINDIR} --moddir ${CURDIR} \
    --java ${BINDIR}/all-java.srclst ${KT_SRSCLIST} ${JAVA_COVERAGE_SRCLIST} \
    --ya-start-command-file ${ext=.gentar:AUTO_INPUT} ${ALL_JAR_SOURCES} ${ext=.java:AUTO_INPUT} ${ext=.kt:AUTO_INPUT} --ya-end-command-file \
    ${hide;input:"build/scripts/process_command_files.py"} \
    ${hide;input:"build/scripts/java_pack_to_file.py"} \
    ${hide;input:"build/scripts/autotar_gendirs.py"}
COLLECT_CLASSPATH=${WRITER_PY} --file ${BINDIR}/bfg.txt -m --ya-start-command-file ${rootrel:MANAGED_PEERS_CLOSURE} $KT_CLASSPATH_ITEM --ya-end-command-file
LINK_CLASSPATH=${YMAKE_PYTHON} ${input:"build/scripts/make_manifest_from_bf.py"} ${BINDIR}/bfg.txt ${ARCADIA_BUILD_ROOT}/bfg.jar
COMPILE_JAVA_SRCLIST=$_JAVAC_RUN_HELPER($JAVAC_CMD)
PACK_JAR=$_PACK_JAR_HELPER($TARGET)
LINK_JAR=${hide:JAVA_FAKEID} ${hide;kv:"p JV"} ${hide;kv:"pc light-blue"} ${hide;kv:"show_out"} ${hide;requirements:"cpu:2"} \
      && $PREPARE_JAR_BUILD \
      && $JAR_GEN_SRCS \
      && $ALL_KT_COMMANDS \
      && $COLLECT_CLASSPATH \
      && $LINK_CLASSPATH \
      && $COMPILE_JAVA_SRCLIST \
      && $LINK_JAR_RESOURCES \
      && ${cwd;suf=/cls:BINDIR} $GENERATE_VCS_JAVA_INFO_NODEP . \
      && $_PACK_SRC_JAR \
      && $_PACK_JNI \
      && $PACK_JAR \
      && $_DO_JAVA_YNDEXING \
      && $_MAKE_JSTYLE_FILE_LIST \
      && $_LINK_UBERJAR \
      && $MAVEN_EXPORT_CMD \
      && $_ADD_HIDDEN_INPUTS($JAVA_EXTERNAL_DEPENDENCIES_VALUE)

# tag:java-specific
_EXT_SRC_JAR=
_EXT_JAR=
_COPY_EXT_SRC_JAR= && $FS_TOOLS md ${BINDIR}/empty && ${cwd;suf=/empty:BINDIR} $JDK_RESOURCE/bin/jar cfvM ${output;pre=${BINDIR}/${MODULE_PREFIX};suf=-sources.jar:REALPRJNAME} .
_DO_USE_EXT_JAR=${hide:JAVA_FAKEID} $FS_TOOLS copy ${input:_EXT_JAR} $TARGET && $_COPY_EXT_SRC_JAR && $MAVEN_EXPORT_CMD
_DO_COPY_EXT_SRC_JAR= && $FS_TOOLS copy $_EXT_SRC_JAR ${output;pre=${BINDIR}/${MODULE_PREFIX};suf=-sources.jar:REALPRJNAME}
macro JAVA_RESOURCE(JAR, SOURCES="") {
    SET(_EXT_SRC_JAR $SOURCES)
    SET(_EXT_JAR $JAR)
}

# tag:java-specific tag:fbs
JAVA_FLATBUFFERS_VERSION = 24.3.25

_KOTLIN_ALLOWED_VERSIONS = contrib/java/org/jetbrains/kotlin/kotlin-allopen/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-allopen-compiler-plugin/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-annotation-processing/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-compiler/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-compiler-embeddable/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-daemon-client/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-daemon-embeddable/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-gradle-plugin-api/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-gradle-plugin-model/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-lombok-compiler-plugin/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-main-kts/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-maven-allopen/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-maven-lombok/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-maven-noarg/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-maven-serialization/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-noarg-compiler-plugin/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-osgi-bundle/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-reflect/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-scripting-common/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-scripting-ide-services/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-scripting-jsr223/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-scripting-jvm/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-scripting-jvm-host/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-script-runtime/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-script-util/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-stdlib/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-stdlib-common/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk7/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk8/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-stdlib-js/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-test/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-test-annotations-common/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-test-common/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-test-js/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-test-junit/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-test-junit5/${_KOTLIN_VERSION} \
        contrib/java/org/jetbrains/kotlin/kotlin-test-testng/${_KOTLIN_VERSION}

# tag:java-specific
module _COMPILABLE_JAR_BASE : _JAR_BASE {
    _GHOST_PEERDIR($_FORCED_DEPENDENCY_MANAGEMENT_VALUE)

    # flatbuffers-java
    DEPENDENCY_MANAGEMENT(contrib/java/com/google/flatbuffers/flatbuffers-java/${JAVA_FLATBUFFERS_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/com/google/flatbuffers/flatbuffers-java EXCEPT contrib/java/com/google/flatbuffers/flatbuffers-java/${JAVA_FLATBUFFERS_VERSION})

    # protobuf-java
    DEPENDENCY_MANAGEMENT(contrib/java/com/google/protobuf/protobuf-java/${JAVA_PROTO_RUNTIME_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/com/google/protobuf/protobuf-java EXCEPT contrib/java/com/google/protobuf/protobuf-java/${JAVA_PROTO_RUNTIME_VERSION})

    # protobuf-javalite
    DEPENDENCY_MANAGEMENT(contrib/java/com/google/protobuf/protobuf-javalite/${JAVA_PROTO_RUNTIME_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/com/google/protobuf/protobuf-javalite EXCEPT contrib/java/com/google/protobuf/protobuf-javalite/${JAVA_PROTO_RUNTIME_VERSION})

    # protobuf-java-util
    DEPENDENCY_MANAGEMENT(contrib/java/com/google/protobuf/protobuf-java-util/${JAVA_PROTO_RUNTIME_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/com/google/protobuf/protobuf-java-util EXCEPT contrib/java/com/google/protobuf/protobuf-java-util/${JAVA_PROTO_RUNTIME_VERSION})

    # protobuf-kotlin
    DEPENDENCY_MANAGEMENT(contrib/java/com/google/protobuf/protobuf-kotlin/${JAVA_PROTO_RUNTIME_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/com/google/protobuf/protobuf-kotlin EXCEPT contrib/java/com/google/protobuf/protobuf-kotlin/${JAVA_PROTO_RUNTIME_VERSION})

    # kotlin
    DEPENDENCY_MANAGEMENT($_KOTLIN_ALLOWED_VERSIONS)

    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-stdlib EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-stdlib/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk7 EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk7/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk8 EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk8/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-stdlib-js EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-stdlib-js/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-stdlib-common EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-stdlib-common/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-reflect EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-reflect/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-osgi-bundle EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-osgi-bundle/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-test EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-test/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-test-junit EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-test-junit/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-test-junit5 EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-test-junit5/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-test-testng EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-test-testng/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-test-js EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-test-js/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-test-common EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-test-common/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-test-annotations-common EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-test-annotations-common/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-main-kts EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-main-kts/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-script-runtime EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-script-runtime/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-script-util EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-script-util/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-scripting-common EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-scripting-common/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-scripting-jsr223 EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-scripting-jsr223/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-scripting-jvm EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-scripting-jvm/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-scripting-jvm-host EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-scripting-jvm-host/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-scripting-ide-services EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-scripting-ide-services/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-compiler EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-compiler/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-compiler-embeddable EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-compiler-embeddable/${_KOTLIN_VERSION})
    CHECK_DEPENDENT_DIRS(DENY PEERDIRS contrib/java/org/jetbrains/kotlin/kotlin-daemon-client EXCEPT contrib/java/org/jetbrains/kotlin/kotlin-daemon-client/${_KOTLIN_VERSION})

}

_JAR_MAIN_CLASS=
macro JAR_MAIN_CLASS(Class) {
    SET(_JAR_MAIN_CLASS ${Class})
}

_JAR_MAIN_SEM=
_ADD_JAR_MAIN_SEM= && app_main_class ${_JAR_MAIN_CLASS}

GRADLE_EXPORT_PUBLISHING=no
_GRADLE_EXPORT_PUBLISHING_SEM=
PUBLISH_MAVEN_VERSION=no
_DO_GRADLE_EXPORT_PUBLISHING_SEM= \
    && publish \
    && publish_group $MAVEN_EXPORT_GROUP_ID \
    && publish_version $PUBLISH_MAVEN_VERSION

_BUILD_JAR_SEM= \
    ${hide:TARGET} ${hide:AUTO_INPUT} ${hide:APPLIED_EXCLUDES} \
    jar $MODDIR $REALPRJNAME \
    && consumer-classpath $EXPORT_GRADLE_CLASSPATH \
    && consumer-jar ${MODDIR}/${REALPRJNAME}.jar \
    && consumer-type library \
    $_JAVAC_SEM \
    $_KOTLIN_SEM \
    $_JAR_MAIN_SEM \
    $_GRADLE_EXPORT_PUBLISHING_SEM \
    $_ANN_PROCESSORS_SEM \
    $_USE_ANNOTATION_PROCESSOR_SEM \
    $_USE_ERROR_PRONE_SEM \
    $_ENABLE_PREVIEW_SEM \
    $_JAR_SOURCE_SET_SEM

_BUILD_PROTO_JAR_SEM= \
    ${hide:target} ${hide:AUTO_INPUT} \
    jar_proto $MODDIR $REALPRJNAME \
    $_JAVA_PROTO_SEM \
    && consumer-classpath $EXPORT_GRADLE_CLASSPATH \
    && consumer-jar ${MODDIR}/${REALPRJNAME}.jar \
    && consumer-type library \
    $_JAVAC_SEM \
    $_ANN_PROCESSORS_SEM \
    $_USE_ANNOTATION_PROCESSOR_SEM \
    $_USE_ERROR_PRONE_SEM \
    $_ENABLE_PREVIEW_SEM \
    $_KOTLIN_SEM

# tag:java-specific tag:internal
### @usage: JAR_LIBRARY() #internal
###
### Reimplementation of the JAVA_LIBRARY with ymake.core.conf and ymake based dependency management
module JAR_LIBRARY: _COMPILABLE_JAR_BASE {
    .EXTS=.jsrc .java .jar .mf .gentar .kt
    .CMD=LINK_JAR
    .SEM=_BUILD_JAR_SEM
    .FINAL_TARGET=yes
    .ALIASES=JAVA_SRCS=FULL_JAVA_SRCS ANNOTATION_PROCESSOR=JAR_ANNOTATION_PROCESSOR
    .RESTRICTED=EXTERNAL_JAR
    .GLOBAL=MAVEN_EXPORT_COORDS
    MODULE_SUFFIX=.jar

    PEERDIR(build/platform/java/jdk)
    PEERDIR+=$JDK_RESOURCE_PEERDIR

    when ($_EXT_SRC_JAR) {
        _COPY_EXT_SRC_JAR=_DO_COPY_EXT_SRC_JAR
    }
    when ($_EXT_JAR) {
        LINK_JAR=$_DO_USE_EXT_JAR
    }
    when ($OPENSOURCE_EXPORT == "no") {
        _BUILD_JAR_SEM=$_SEM_IGNORED
    }
    when ($_JAR_MAIN_CLASS) {
        _JAR_MAIN_SEM=$_ADD_JAR_MAIN_SEM
    }
    when ($GRADLE_EXPORT_PUBLISHING == "yes") {
        _GRADLE_EXPORT_PUBLISHING_SEM=$_DO_GRADLE_EXPORT_PUBLISHING_SEM
    }

    # in the ideal world this statement must be under condition bellow
    DEPENDENCY_MANAGEMENT(contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk8/${_KOTLIN_VERSION})
    when ($WITH_KOTLIN_VALUE) {
        KT_SRSCLIST=$KT_SRSCLIST_FLAG
        _MAKE_LINT_KT_FILES_LIST = $YMAKE_PYTHON ${input:"build/scripts/kt_copy.py"} $KT_SRCLIST ${noauto;output:"all-kt-sources.txt"} $(SOURCE_ROOT) $(BUILD_ROOT)
        ALL_KT_COMMANDS=&& $COLLECT_KT_CLASSPATH && $LINK_KT_CLASSPATH
        when ($WITH_KAPT_VALUE == "yes") {
            # For Kapt usage see: https://kotlinlang.org/docs/kapt.html#using-in-cli
            # See for kapt.kotlin.generated: https://github.com/JetBrains/kotlin/blob/master/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGeneration/build.txt
            _KAPT_OPTS=-Xplugin=${tool:"contrib/java/org/jetbrains/kotlin/kotlin-annotation-processing/1.9.24"} $KT_KAPT_PLUGIN_OPTS
            _RUN_KAPT=${YMAKE_PYTHON} ${input:"build/scripts/with_kapt_args.py"} ${pre=--ap-classpath :KT_KAPT_AP_CLASSPATH} -- $COMPILE_KT $_KAPT_OPTS
            _APPEND_KAPT_GENERATED_SRCS=$YMAKE_PYTHON ${input:"build/scripts/resolve_java_srcs.py"} -d $KT_KAPT_SOURCES_DIR --include-patterns '**/*.java' '**/*.kt' --resolve-kotlin --append -s ${BINDIR}/all-java.srclst -k $KT_SRCLIST -r ${BINDIR}/not-used.txt

              ALL_KT_COMMANDS+=&& $_RUN_KAPT && $_APPEND_KAPT_GENERATED_SRCS
        }
          ALL_KT_COMMANDS+=&& $COMPILE_KT && $_MAKE_LINT_KT_FILES_LIST
        LINK_JAR_RESOURCES+=&& $FS_TOOLS copy_all_files ${KT_CLASSES_DIR} ${BINDIR}/cls
        PEERDIR+=build/platform/java/kotlin contrib/java/org/jetbrains/kotlin/kotlin-stdlib-jdk8
        when($WITH_KOTLINC_PLUGIN_ALLOPEN) {
            KOTLINC_OPTS_VALUE+=-Xplugin=${KOTLIN_COMPILER_RESOURCE_GLOBAL}/plugins/kotlin-allopen-plugin.jar
        }
        when($WITH_KOTLINC_PLUGIN_LOMBOK) {
            KOTLINC_OPTS_VALUE+=-Xplugin=${KOTLIN_COMPILER_RESOURCE_GLOBAL}/plugins/kotlin-lombok-plugin.jar
        }
        when($WITH_KOTLINC_PLUGIN_NOARG) {
            KOTLINC_OPTS_VALUE+=-Xplugin=${KOTLIN_COMPILER_RESOURCE_GLOBAL}/plugins/kotlin-noarg-plugin.jar
        }
        when($WITH_KOTLINC_PLUGIN_SERIALIZATION) {
            KOTLINC_OPTS_VALUE+=-Xplugin=${KOTLIN_COMPILER_RESOURCE_GLOBAL}/plugins/kotlin-serialization-plugin.jar
        }
        when($WITH_KOTLINC_PLUGIN_DETEKT) {
            KOTLINC_OPTS_VALUE+=-Xplugin=${tool:"devtools/detekt-compiler-plugin"}
            KOTLINC_OPTS_VALUE+=-P plugin:detekt-compiler-plugin:report=xml:${BINDIR}/misc/detekt-report.xml
            # If there are no kt sources, the report won't be generated, however the file must be always present.
            ALL_KT_COMMANDS+=&& $YMAKE_PYTHON ${input:"build/scripts/touch.py"} ${BINDIR}/misc/detekt-report.xml
            ALL_KT_COMMANDS+=&& $FS_TOOLS copy ${BINDIR}/misc/detekt-report.xml ${noauto;output:"detekt-report.xml"}
        }
        # Must be in sync with KT_CLASSES_DIR!
        # There are problems in JDK13 with abs paths in classpath baked into jar file manifest. Using relative path
        # here assumes that jar file with classpath for javac located in the $ARCADIA_BUILD_ROOT
        KT_CLASSPATH_ITEM=$MODDIR/kt_cls
    }
    otherwise {
        KT_SRSCLIST=
        ALL_KT_COMMANDS=
        KT_CLASSES=
    }

    when ($MAVEN_EXPORT == "yes") {
        when ($MAVEN_DEPLOY == "yes") {
            PEERDIR+=build/external_resources/maven
            MAVEN_EXPORT_CMD= && $MAVEN_EXPORT_GEN_DEPLST && $MAVEN_EXPORT_GEN_POM && $MAVEN_DEPLOY_CMD
        }
        otherwise {
            MAVEN_EXPORT_CMD= && $MAVEN_EXPORT_GEN_DEPLST && $MAVEN_EXPORT_GEN_POM
        }
        MAVEN_EXPORT_COORDS_GLOBAL=$MAVEN_EXPORT_GROUP_ID:${MODULE_PREFIX}${REALPRJNAME}:${MAVEN_EXPORT_VERSION}:
    }

    when ($SOURCES_JAR == "yes") {
        _PACK_SRC_JAR=$_PACK_SRC_JAR_IMPL
        MAVEN_DEPLOY_SOURCES=-Dsources=${output;pre=${BINDIR}/${MODULE_PREFIX};suf=-sources.jar:REALPRJNAME}
    }

    when ($JAVA_COVERAGE == "yes") {
        JAVA_COVERAGE_SRCLIST=$JAVA_COVERAGE_SRCLIST_FLAG
    }

    when ($MAKE_UBERJAR_VALUE == "yes") {
        _LINK_UBERJAR=$_DO_LINK_UBERJAR
        PACK_JAR=$_PACK_JAR_HELPER(${BINDIR}/${REALPRJNAME}.lib.jar)
        # TODO: This condition is incorrect in case of autoinputs _UBERJAR_SELF should be empty only for
        # modules without AUTO_INPUT and without JAVA_SRCS added inputs.
        when($ALL_JAR_SOURCES) {
            _UBERJAR_SELF=--jar ${BINDIR}/${REALPRJNAME}.lib.jar
        }
        PEERDIR+=build/platform/java/uberjar
        PEERDIR+=$UBERJAR_RESOURCE_PEERDIR
    }

    when($JAVA_YNDEXING == "yes") {
        PEERDIR+=build/platform/java/kythe
        _DO_JAVA_YNDEXING=&& $_JAVAC_RUN_HELPER($_JAVA_YNDEXING_CMD) && ${cwd:BINDIR} $YMAKE_PYTHON ${input:"build/scripts/find_and_tar.py"} kindex.tar .kzip ${hide;output;tared:"kindex.tar"}
    }

    when($ERROR_PRONE_VALUE) {
        PEERDIR+=$ERROR_PRONE_PEERDIR
        RUN_JAVAC_ARGS=--error-prone $ERROR_PRONE_RESOURCE/error_prone.jar
    }

    when($ERROR_PRONE_VALUE && $JDK_REAL_VERSION == "17") {
        JAVAC_FLAGS_VALUE+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
        JAVAC_OPTS+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
    }

    when($ERROR_PRONE_VALUE && $JDK_REAL_VERSION == "20") {
        JAVAC_FLAGS_VALUE+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
        JAVAC_OPTS+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
    }

    when($ERROR_PRONE_VALUE && $JDK_REAL_VERSION == "21") {
        JAVAC_FLAGS_VALUE+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
        JAVAC_OPTS+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
    }

    when($ERROR_PRONE_VALUE && $JDK_REAL_VERSION == "22") {
        JAVAC_FLAGS_VALUE+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
        JAVAC_OPTS+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
    }

    when($ERROR_PRONE_VALUE && $JDK_REAL_VERSION == "23") {
        JAVAC_FLAGS_VALUE+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
        JAVAC_OPTS+=$ERROR_PRONE_JDK16PLUS_ADD_OPENS
    }

    when($ERROR_PRONE_VALUE && $ERROR_PRONE_VERSION == "2.7.1") {
        JAVAC_FLAGS_VALUE+=$ERROR_PRONE_2_7_1_FORCED_OPTS
        JAVAC_OPTS+=$ERROR_PRONE_2_7_1_FORCED_OPTS
    }

    when ($JAVA_ADD_DLLS_VALUE == "yes") {
        CONSUME_NON_MANAGEABLE_PEERS=yes
        _PACK_JNI=$_PACK_JNI_CMD
    }

    when ($LINT_LEVEL_VALUE != "none") {
        _MAKE_JSTYLE_FILE_LIST= && ${WRITER_PY} --file ${noauto;output:"lint-java.srclst"} -m --ya-start-command-file $LINT_JAVA_SOURCES --ya-end-command-file
    }

    SET(MODULE_TYPE JAVA_LIBRARY)
    _ADD_KOTLIN_STYLE_CHECKS($(BUILD_ROOT)/$MODDIR/all-kt-sources.txt REQUIREMENTS cpu:2)
    _ADD_JAVA_STYLE_CHECKS($(BUILD_ROOT)/$MODDIR/lint-java.srclst::$(SOURCE_ROOT))
    _ADD_DETEKT_REPORT_CHECK($(BUILD_ROOT)/$MODDIR/detekt-report.xml)
    _ADD_CLASSPATH_CLASH_CHECK()
    JAVA_MODULE()
}

# tag:java-specific
_SCRIPTGEN_FLAGS=
macro _GEN_JAVA_SCRIPT_IMPL(Out, Template, Props...) {
    .CMD=$SCRIPTGEN_RESOURCE_GLOBAL/scriptgen --java $JDK_RESOURCE/bin/java --output ${output:Out} --template ${input:Template} ${_SCRIPTGEN_FLAGS} -D JAR_NAME=${REALPRJNAME}.jar -D CLASSPATH=${join;pre="::";nopath;ext=.jar:MANAGED_PEERS_CLOSURE} -D PROJECT_DIR=${MODDIR} -D JAR_BASENAME=${REALPRJNAME}  -D MAIN_CLASS=${_JAR_MAIN_CLASS} -D ENABLE_PREVIEW_VALUE=${ENABLE_PREVIEW_VALUE} $Props
}

# tag:java-specific
_GEN_USERSCRIPTS=
macro _ADD_GEN_JAVA_SCRIPT(Out, Template, Props...) {
    SET_APPEND(_GEN_USERSCRIPTS && \$_GEN_JAVA_SCRIPT_IMPL($Out $Template $Props))
}

# tag:java-specific
_PACK_JDK=

# tag:java-specific
DO_GEN_JAVA_RUN_SH=
_SOURCE_JARS=
_SOURCE_JARS_CPLIST=
_GEN_JAVA_RUN_SH_OUTPUT=run.sh
when ($HOST_OS_WINDOWS == "yes") {
    _GEN_JAVA_RUN_SH_OUTPUT=run.bat
}
GEN_JAVA_RUN_SH=$SCRIPTGEN_RESOURCE_GLOBAL/scriptgen --java $JDK_RESOURCE/bin/java --output ${output:_GEN_JAVA_RUN_SH_OUTPUT} \
    -D GENERATE_DEFAULT_RUNNER=yes \
    -D JAR_NAME=${REALPRJNAME}.jar \
    -D CLASSPATH=${join;pre="::";nopath:MANAGED_PEERS_CLOSURE} \
    -D PROJECT_DIR=${REALPRJNAME} \
    -D JAR_BASENAME=${REALPRJNAME} \
    -D MAIN_CLASS=${_JAR_MAIN_CLASS} \
    -D ENABLE_PREVIEW=${ENABLE_PREVIEW_VALUE}
GEN_RUN_CP=${WRITER_PY} --file ${BINDIR}/run-bf.txt -Q -m --ya-start-command-file ${qe;pre=$REALPRJNAME/;nopath:MANAGED_PEERS_CLOSURE} --ya-end-command-file && ${YMAKE_PYTHON} ${input:"build/scripts/make_manifest_from_bf.py"} ${BINDIR}/run-bf.txt ${TARGET}
COLLECT_JAR_PROGRAM_CP=$FS_TOOLS link_or_copy_to_dir \
    --ya-start-command-file \
    ${ext=.jar:MANAGED_PEERS_CLOSURE} \
    ${ext=.so:MANAGED_PEERS_CLOSURE} \
    ${ext=.dll:MANAGED_PEERS_CLOSURE} \
    ${ext=.dylib:MANAGED_PEERS_CLOSURE} \
    ${_SOURCE_JARS} \
    --ya-end-command-file \
    ${BINDIR}/${REALPRJNAME} \
    ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.jar:MANAGED_PEERS_CLOSURE} \
    ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.so:MANAGED_PEERS_CLOSURE} \
    ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dll:MANAGED_PEERS_CLOSURE} \
    ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dylib:MANAGED_PEERS_CLOSURE}
MAKE_JAR_PROGRAM_CPLST=${MAKE_JAVA_CLASSPATH_FILE} --from-args ${output;pre=$MODULE_PREFIX;suf=${MODULE_SUFFIX}.cplst:REALPRJNAME} --ya-start-command-file ${rootrel;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.jar:MANAGED_PEERS_CLOSURE} ${_SOURCE_JARS_CPLIST} --ya-end-command-file
TAR_CLASSPATH= && $YMAKE_PYTHON ${input:"build/scripts/find_and_tar.py"} ${output;pre=$MODULE_PREFIX;suf=.tar:REALPRJNAME} ${cwd;pre=$BINDIR/:REALPRJNAME}
DO_TAR_CLASSPATH=
LINK_JAR_PROGRAM=${hide:JAVA_FAKEID} $FS_TOOLS md ${BINDIR}/${REALPRJNAME} \
    && $COLLECT_JAR_PROGRAM_CP \
    && $DO_GEN_JAVA_RUN_SH \
    && $GEN_RUN_CP \
    && $MAKE_JAR_PROGRAM_CPLST \
    && $DO_TAR_CLASSPATH \
    && $_GEN_USERSCRIPTS \
    && $_PACK_JDK \
    && ${hide;kv:"p JP"} ${hide;kv:"pc light-blue"} ${hide;kv:"show_out"}

# tag:java-specific
# UBERJAR program link command
LINK_UBERJAR_PROGRAM=${hide:JAVA_FAKEID} ${hide;kv:"p UJ"} ${MAKE_JAVA_CLASSPATH_FILE} --from-args ${output;pre=$MODULE_PREFIX;suf=${MODULE_SUFFIX}.cplst:REALPRJNAME} $TARGET \
                     && $FS_TOOLS md ${BINDIR}/${REALPRJNAME} \
                     && $FS_TOOLS link_or_copy ${BINDIR}/${REALPRJNAME}.jar $TARGET \
                     && $FS_TOOLS link_or_copy_to_dir --ya-start-command-file ${BINDIR}/${REALPRJNAME}.jar ${ext=.so:MANAGED_PEERS_CLOSURE} ${ext=.dll:MANAGED_PEERS_CLOSURE} ${ext=.dylib:MANAGED_PEERS_CLOSURE} ${_SOURCE_JARS} --ya-end-command-file ${BINDIR}/${REALPRJNAME} ${hide;output;suf=.jar;pre=$REALPRJNAME/:REALPRJNAME} ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.so:MANAGED_PEERS_CLOSURE} ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dll:MANAGED_PEERS_CLOSURE} ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;ext=.dylib:MANAGED_PEERS_CLOSURE} \
                     && $DO_TAR_CLASSPATH \
                     && $_GEN_USERSCRIPTS \
                     && $_PACK_JDK

# tag:java-specific
RUN_WITH_SOURCES=no
# TODO jbuild creates tar with all classpath deps by default and some projects rely on this. In ymake build this tar file creation is not needed and should be disabled by default in future
TARED_CLASSPATH=yes
_JAR_SRCS_CALLED=no

# tag:java-specific
macro _MARK_JAVA_PROG_WITH_SOURCES(Args...) {
    ENABLE(_JAR_SRCS_CALLED)
}

# tag:java-specific
module _JAR_RUNNABLE: _COMPILABLE_JAR_BASE {
    .FINAL_TARGET=yes
    .CMD=LINK_JAR_PROGRAM
    .SEM=_SEM_IGNORED
    .ALIASES=JAVA_SRCS=_MARK_JAVA_PROG_WITH_SOURCES
    .ALLOWED=WITH_JDK GENERATE_SCRIPT
    .PEERDIR_POLICY=as_build_from

    MODULE_SUFFIX=.run.cp.jar
    CONSUME_NON_MANAGEABLE_PEERS=yes

    when ($RUN_WITH_SOURCES == "yes") {
        _SOURCE_JARS=${suf=-sources.jar;noext;ext=.jar:MANAGED_PEERS_CLOSURE} ${hide;late_out;pre=$BINDIR/$REALPRJNAME/;nopath;suf=-sources.jar;noext;ext=.jar:MANAGED_PEERS_CLOSURE}
        _SOURCE_JARS_CPLIST=${rootrel;pre=$BINDIR/$REALPRJNAME/;nopath;suf=-sources.jar;noext;ext=.jar:MANAGED_PEERS_CLOSURE}
    }

    when ($TARED_CLASSPATH == "yes") {
        DO_TAR_CLASSPATH=$TAR_CLASSPATH
    }

    when ($DISABLE_SCRIPTGEN) {
        DO_GEN_JAVA_RUN_SH=
    }
    otherwise {
        DO_GEN_JAVA_RUN_SH=$GEN_JAVA_RUN_SH
        PEERDIR+=build/platform/java/scriptgen
    }

    when ($MAKE_UBERJAR_VALUE == "yes") {
        LINK_JAR_PROGRAM=$LINK_UBERJAR_PROGRAM
        DYNAMIC_LINK=no
        _SCRIPTGEN_FLAGS=-D IS_UBERJAR=yes
    }
    otherwise {
        _SCRIPTGEN_FLAGS=-D IS_UBERJAR=no
    }
    CHECK_PROVIDES()
}

# tag:java-specific
LINK_JAR_TEST=${hide:JAVA_FAKEID} ${WRITER_PY} --file ${BINDIR}/run-bf.txt -Q -m --ya-start-command-file ${ext=.jar:MANAGED_PEERS_CLOSURE} --ya-end-command-file && ${YMAKE_PYTHON} ${input:"build/scripts/make_manifest_from_bf.py"} ${BINDIR}/run-bf.txt ${TARGET} ${hide;kv:"p JT"}
module _JAR_TEST: _COMPILABLE_JAR_BASE {
    .FINAL_TARGET=yes
    .CMD=LINK_JAR_TEST
    .DEFAULT_NAME_GENERATOR=FullPath
    CONSUME_NON_MANAGEABLE_PEERS=yes

    SET(MODULE_SUFFIX .test.cp.jar)
    JAVA_TEST()
    CHECK_PROVIDES()
    SET_APPEND(_MAKEFILE_INCLUDE_LIKE_DEPS canondata/result.json)
}

# tag:java-specific
JDK_REAL_VERSION=
JDK_VERSION=

when ($JDK_VERSION == "23") {
    JDK_REAL_VERSION=23
}
elsewhen ($JDK_VERSION == "22") {
    JDK_REAL_VERSION=22
}
elsewhen ($JDK_VERSION == "21") {
    JDK_REAL_VERSION=21
}
elsewhen ($JDK_VERSION == "20") {
    JDK_REAL_VERSION=20
}
elsewhen ($JDK_VERSION == "17") {
    JDK_REAL_VERSION=17
}
elsewhen ($JDK_VERSION == "11") {
    JDK_REAL_VERSION=11
}
elsewhen ($MAPSMOBI_BUILD_TARGET && $OS_ANDROID) {
    JDK_REAL_VERSION=11
}
otherwise {
    JDK_REAL_VERSION=17
}

# tag:java-specific
# remove extra peerdir to jdk11 after https://st.yandex-team.ru/DEVTOOLS-8851 is done
when ($USE_SYSTEM_JDK) {
    JDK_RESOURCE_PEERDIR=
}
otherwise {
    when ($JDK_REAL_VERSION == "23") {
        JDK_RESOURCE_PEERDIR=build/platform/java/jdk/jdk23 build/platform/java/jdk/jdk17
    }
    when ($JDK_REAL_VERSION == "22") {
        JDK_RESOURCE_PEERDIR=build/platform/java/jdk/jdk22 build/platform/java/jdk/jdk17
    }
    when ($JDK_REAL_VERSION == "21") {
        JDK_RESOURCE_PEERDIR=build/platform/java/jdk/jdk21 build/platform/java/jdk/jdk17
    }
    when ($JDK_REAL_VERSION == "20") {
        JDK_RESOURCE_PEERDIR=build/platform/java/jdk/jdk20 build/platform/java/jdk/jdk17
    }
    when ($JDK_REAL_VERSION == "17") {
        # need jdk11 for spare parts in "host" platform
        JDK_RESOURCE_PEERDIR=build/platform/java/jdk/jdk17 build/platform/java/jdk/jdk11
    }
    when ($JDK_REAL_VERSION == "11") {
        JDK_RESOURCE_PEERDIR=build/platform/java/jdk/jdk11 build/platform/java/jdk/jdk17
    }
}

# tag:java-specific
when ($JDK_REAL_VERSION == "23") {
    UBERJAR_RESOURCE_PEERDIR=build/platform/java/uberjar/uberjar23
}
when ($JDK_REAL_VERSION == "22") {
    UBERJAR_RESOURCE_PEERDIR=build/platform/java/uberjar/uberjar22
}
when ($JDK_REAL_VERSION == "21") {
    UBERJAR_RESOURCE_PEERDIR=build/platform/java/uberjar/uberjar21
}
when ($JDK_REAL_VERSION == "20") {
    UBERJAR_RESOURCE_PEERDIR=build/platform/java/uberjar/uberjar20
}
when ($JDK_REAL_VERSION == "17") {
    UBERJAR_RESOURCE_PEERDIR=build/platform/java/uberjar/uberjar17
}
when ($JDK_REAL_VERSION == "11") {
    UBERJAR_RESOURCE_PEERDIR=build/platform/java/uberjar/uberjar11
}

# tag:java-specific
JAVAC_OPTS=
when ($USE_SYSTEM_JDK) {
    JDK_RESOURCE=$USE_SYSTEM_JDK
}
otherwise {
    when ($JDK_REAL_VERSION == "23") {
        JDK_RESOURCE=$JDK23_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "22") {
        JDK_RESOURCE=$JDK22_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "21") {
        JDK_RESOURCE=$JDK21_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "20") {
        JDK_RESOURCE=$JDK20_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "17") {
        JDK_RESOURCE=$JDK17_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "11") {
        JDK_RESOURCE=$JDK11_RESOURCE_GLOBAL
    }
}

# tag:java-specific
when (!$USE_SYSTEM_ERROR_PRONE) {
    # Still not done: DTCC-667
    when ($JDK_REAL_VERSION == "11") {
        ERROR_PRONE_VERSION=2.7.1
        ERROR_PRONE_PEERDIR=build/platform/java/error_prone/2.7.1
        ERROR_PRONE_RESOURCE=$ERROR_PRONE_2_7_1_RESOURCE_GLOBAL
    }
    elsewhen ($JDK_REAL_VERSION == "17") {
        ERROR_PRONE_VERSION=2.10.0
        ERROR_PRONE_PEERDIR=build/platform/java/error_prone/2.10.0
        ERROR_PRONE_RESOURCE=$ERROR_PRONE_2_10_0_RESOURCE_GLOBAL
    }
    elsewhen ($JDK_REAL_VERSION == "20") {
        ERROR_PRONE_VERSION=2.18.0
        ERROR_PRONE_PEERDIR=build/platform/java/error_prone/2.18.0
        ERROR_PRONE_RESOURCE=$ERROR_PRONE_2_18_0_RESOURCE_GLOBAL
    }
    elsewhen ($JDK_REAL_VERSION == "21") {
        ERROR_PRONE_VERSION=2.30.0
        ERROR_PRONE_PEERDIR=build/platform/java/error_prone/2.30.0
        ERROR_PRONE_RESOURCE=$ERROR_PRONE_2_30_0_RESOURCE_GLOBAL
    }
    elsewhen ($JDK_REAL_VERSION == "22") {
        ERROR_PRONE_VERSION=2.30.0
        ERROR_PRONE_PEERDIR=build/platform/java/error_prone/2.30.0
        ERROR_PRONE_RESOURCE=$ERROR_PRONE_2_30_0_RESOURCE_GLOBAL
    }
    elsewhen ($JDK_REAL_VERSION == "23") {
        ERROR_PRONE_VERSION=2.30.0
        ERROR_PRONE_PEERDIR=build/platform/java/error_prone/2.30.0
        ERROR_PRONE_RESOURCE=$ERROR_PRONE_2_30_0_RESOURCE_GLOBAL
    }
    otherwise {
        ERROR_PRONE_VERSION=2.7.1
        ERROR_PRONE_PEERDIR=build/platform/java/error_prone
        ERROR_PRONE_RESOURCE=$ERROR_PRONE_RESOURCE_GLOBAL
    }
}
otherwise {
    ERROR_PRONE_VERSION=2.7.1
    ERROR_PRONE_PEERDIR=build/platform/java/error_prone
    ERROR_PRONE_RESOURCE=$ERROR_PRONE_RESOURCE_GLOBAL
}

# tag:java-specific
when ($USE_SYSTEM_UBERJAR) {
    UBERJAR_RESOURCE=$USE_SYSTEM_UBERJAR
}
otherwise {
    when ($JDK_REAL_VERSION == "23") {
        UBERJAR_RESOURCE=$UBERJAR23_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "22") {
        UBERJAR_RESOURCE=$UBERJAR22_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "21") {
        UBERJAR_RESOURCE=$UBERJAR21_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "20") {
        UBERJAR_RESOURCE=$UBERJAR20_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "17") {
        UBERJAR_RESOURCE=$UBERJAR17_RESOURCE_GLOBAL
    }
    when ($JDK_REAL_VERSION == "11") {
        UBERJAR_RESOURCE=$UBERJAR11_RESOURCE_GLOBAL
    }
}

# tag:java-specific
when ($JDK_REAL_VERSION == "23") {
    WITH_JDK_RESOURCE=$WITH_JDK23_RESOURCE_GLOBAL
}
when ($JDK_REAL_VERSION == "22") {
    WITH_JDK_RESOURCE=$WITH_JDK22_RESOURCE_GLOBAL
}
when ($JDK_REAL_VERSION == "21") {
    WITH_JDK_RESOURCE=$WITH_JDK21_RESOURCE_GLOBAL
}
when ($JDK_REAL_VERSION == "20") {
    WITH_JDK_RESOURCE=$WITH_JDK20_RESOURCE_GLOBAL
}
when ($JDK_REAL_VERSION == "17") {
    WITH_JDK_RESOURCE=$WITH_JDK17_RESOURCE_GLOBAL
}
when ($JDK_REAL_VERSION == "11") {
    WITH_JDK_RESOURCE=$WITH_JDK11_RESOURCE_GLOBAL
}

# tag:java-specific
EXTERNAL_JAVA_JDK_RESOURCE=
EXTERNAL_JAVA_EXTRA_PEERDIR=
when ($USE_SYSTEM_JDK) {
    EXTERNAL_JAVA_EXTRA_PEERDIR=
    EXTERNAL_JAVA_JDK_RESOURCE=$USE_SYSTEM_JDK
}
elsewhen ($JDK_VERSION == "") {
    EXTERNAL_JAVA_JDK_RESOURCE=$JDK11_RESOURCE_GLOBAL
    EXTERNAL_JAVA_EXTRA_PEERDIR=build/platform/java/jdk/jdk11
}
otherwise {
    EXTERNAL_JAVA_JDK_RESOURCE=$JDK_RESOURCE
}
COMPILE_JAVA=${cwd:ARCADIA_BUILD_ROOT} $YMAKE_PYTHON3 ${input:"build/scripts/compile_java.py"} --ya-start-command-file --java-bin $EXTERNAL_JAVA_JDK_RESOURCE/bin/java --javac-bin $EXTERNAL_JAVA_JDK_RESOURCE/bin/javac --jar-bin $JDK_RESOURCE/bin/jar --kotlin-compiler $KOTLIN_COMPILER_RESOURCE_GLOBAL/kotlin-compiler.jar $JAVA_VCS_MF_ARG $PACKAGE_PREFIX_ARGS --jar-output $TARGET --srcs-jar-output ${output;suf=-sources.jar:REALPRJNAME} $AUTO_INPUT DELIM $JAVAC_OPTS DELIM $MANAGED_PEERS_CLOSURE DELIM -no-stdlib -module-name $REALPRJNAME -jvm-target ${KOTLIN_JVM_TARGET} ${KOTLINC_OPTS_VALUE} --ya-end-command-file ${hide;kv:"p JV"} ${hide;kv:"pc light-blue"} ${hide;kv:"show_out"} ${hide;requirements:"cpu:2"} ${hide;input:"build/scripts/java_command_file.py"} ${hide;input:"build/scripts/process_command_files.py"}

ARGS_DELIM="MACRO_CALLS_DELIM"

SYSTEM_PROPERTIES_VALUE=
### @usage: SYSTEM_PROPERTIES([<Key Value>...] [<File Path>...])
###
### List of Key,Value pairs that will be available to test via System.getProperty().
### FILE means that parst should be read from file specifies as Path.
###
### Documentation: https://wiki.yandex-team.ru/yatool/test/
macro SYSTEM_PROPERTIES(Args...) {
    SET_APPEND(SYSTEM_PROPERTIES_VALUE $Args)
}

# tag:java-specific
JVM_ARGS_VALUE=-ea
### @usage: JVM_ARGS(Args...)
###
### Arguments to run Java programs in tests.
###
### Documentation: https://wiki.yandex-team.ru/yatool/test/
macro JVM_ARGS(Args...) {
    SET_APPEND(JVM_ARGS_VALUE $Args)
}

# tag:java-specific
CHECK_JAVA_DEPS_VALUE=
### @usage: CHECK_JAVA_DEPS(<yes|no|strict>)
###
### Check for different classes with duplicate name in classpath.
###
### Documentation: https://wiki.yandex-team.ru/yatool/test/
macro CHECK_JAVA_DEPS(Arg) {
    SET(CHECK_JAVA_DEPS_VALUE $Arg)
}

ERROR_PRONE_VALUE=
_USE_ERROR_PRONE_SEM=
### @usage: USE_ERROR_PRONE()
###
### Use errorprone instead of javac for .java compilation.
macro USE_ERROR_PRONE() {
    SET(ERROR_PRONE_VALUE yes)
    SET(_USE_ERROR_PRONE_SEM && use_errorprone)
}

# tag:java-specific
MAKE_UBERJAR_VALUE=
### @usage: UBERJAR()
###
### UBERJAR is a single all-in-one jar-archive that includes all its Java dependencies (reachable PEERDIR).
### It also supports shading classes inside the archive by moving them to a different package (similar to the maven-shade-plugin).
### Use UBERJAR inside JAVA_PROGRAM module.
###
### You can use the following macros to configure the archive:
### 1. UBERJAR_HIDING_PREFIX prefix for classes to shade (classes remain in their packages by default)
### 2. UBERJAR_HIDE_INCLUDE_PATTERN include classes matching this patterns to shading, include LDC mapping
### 3. UBERJAR_HIDE_EXCLUDE_PATTERN exclude classes matching this patterns from shading (if enabled).
### 4. UBERJAR_PATH_EXCLUDE_PREFIX the prefix for classes that should not get into the jar archive (all classes are placed into the archive by default)
### 5. UBERJAR_MANIFEST_TRANSFORMER_MAIN add ManifestResourceTransformer class to uberjar processing and specify main-class
### 6. UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE add ManifestResourceTransformer class to uberjar processing and specify some attribute
### 7. UBERJAR_APPENDING_TRANSFORMER add AppendingTransformer class to uberjar processing
### 8. UBERJAR_SERVICES_RESOURCE_TRANSFORMER add ServicesResourceTransformer class to uberjar processing
###
### Documentation: https://wiki.yandex-team.ru/yatool/java/
###
### @see: [JAVA_PROGRAM](#module_JAVA_PROGRAM), [UBERJAR_HIDING_PREFIX](#macro_UBERJAR_HIDING_PREFIX), [UBERJAR_HIDE_INCLUDE_PATTERN](#macro_UBERJAR_HIDE_INCLUDE_PATTERN) [UBERJAR_HIDE_EXCLUDE_PATTERN](#macro_UBERJAR_HIDE_EXCLUDE_PATTERN), [UBERJAR_PATH_EXCLUDE_PREFIX](#macro_UBERJAR_PATH_EXCLUDE_PREFIX)
macro UBERJAR() {
    SET(MAKE_UBERJAR_VALUE yes)
    DISABLE(PASS_PEERS)
}

# tag:java-specific
UBERJAR_PREFIX_VALUE=
UBERJAR_PREFIX_FLAG=
### @usage: UBERJAR_HIDING_PREFIX(Arg)
###
### Set prefix for classes to shade. All classes in UBERJAR will be moved into package prefixed with Arg.
### Classes remain in their packages by default.
###
### @see: [UBERJAR](#macro_UBERJAR)
macro UBERJAR_HIDING_PREFIX(Arg) {
    SET(UBERJAR_PREFIX_VALUE $Arg)
    SET(UBERJAR_PREFIX_FLAG ${pre=--shade-prefix :Arg})
}

# tag:java-specific
UBERJAR_HIDE_EXCLUDE_VALUE=
UBERJAR_HIDE_EXCLUDE_FLAGS=
### @usage: UBERJAR_HIDE_EXCLUDE_PATTERN(Args...)
###
### Exclude classes matching this patterns from shading (if enabled).
### Pattern may contain '*' and '**' globs.
### Shading is enabled for UBERJAR program using UBERJAR_HIDING_PREFIX macro. If this macro is not specified all classes are shaded.
###
### @see: [UBERJAR](#macro_UBERJAR), [UBERJAR_HIDING_PREFIX](#macro_UBERJAR_HIDING_PREFIX)
macro UBERJAR_HIDE_EXCLUDE_PATTERN(Args...) {
    SET_APPEND(UBERJAR_HIDE_EXCLUDE_VALUE $ARGS_DELIM $Args)
    SET_APPEND(UBERJAR_HIDE_EXCLUDE_FLAGS ${pre=--shade-exclude :Args})
}


UBERJAR_HIDE_INCLUDE_VALUE=
UBERJAR_HIDE_INCLUDE_FLAGS=
### @usage: UBERJAR_HIDE_INCLUDE_PATTERN(Args...)
###
### Include classes matching this patterns to shading, enabled LDC processing.
### Pattern may contain '*' and '**' globs.
### Shading is enabled for UBERJAR program using UBERJAR_HIDING_PREFIX macro. If this macro is not specified all classes are shaded.
###
### @see: [UBERJAR](#macro_UBERJAR), [UBERJAR_HIDING_PREFIX](#macro_UBERJAR_HIDING_PREFIX)
macro UBERJAR_HIDE_INCLUDE_PATTERN(Args...) {
    SET_APPEND(UBERJAR_HIDE_INCLUDE_VALUE $ARGS_DELIM $Args)
    SET_APPEND(UBERJAR_HIDE_INCLUDE_FLAGS ${pre=--shade-include :Args})
}

# tag:java-specific
UBERJAR_PATH_EXCLUDES=
UBERJAR_PATH_EXCLUDE_VALUE=
### @usage: UBERJAR_PATH_EXCLUDE_PREFIX(Args...)
###
### Exclude classes matching this patterns from UBERJAR.
### By default all dependencies of UBERJAR program will lend in a .jar archive.
###
### @see: [UBERJAR](#macro_UBERJAR)
macro UBERJAR_PATH_EXCLUDE_PREFIX(Args...) {
    SET_APPEND(UBERJAR_PATH_EXCLUDE_VALUE $ARGS_DELIM $Args)
    SET_APPEND(UBERJAR_PATH_EXCLUDES ${pre=--uber-exclude :Args})
}

# tag:java-specific
UBERJAR_MANIFEST_TRANSFORMER_MAIN_VALUE=
UBERJAR_MANIFEST_TRANSFORMER_MAIN_FLAG=
### @usage: UBERJAR_MANIFEST_TRANSFORMER_MAIN(Main)
###
### Transform manifest.mf for UBERJAR() java programs, set main-class attribute
###
### @see: [UBERJAR](#macro_UBERJAR)
macro UBERJAR_MANIFEST_TRANSFORMER_MAIN(Main) {
    SET(UBERJAR_MANIFEST_TRANSFORMER_MAIN_VALUE $Main)
    SET(UBERJAR_MANIFEST_TRANSFORMER_MAIN_FLAG --manifest-main $Main)
}

# tag:java-specific
UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE_VALUE=
UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE_FLAGS=
### @usage: UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE(Key, Value)
###
### Transform manifest.mf for UBERJAR() java programs, set attribute
###
### @see: [UBERJAR](#macro_UBERJAR)
macro UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE(Key, Values...) {
    SET_APPEND(UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE_VALUE $ARGS_DELIM $Key : $Values)
    SET_APPEND(UBERJAR_MANIFEST_TRANSFORMER_ATTRIBUTE_FLAGS --manifest-attribute ${Key}:'${Values}')
}

# tag:java-specific
UBERJAR_APPENDING_TRANSFORMER_VALUE=
UBERJAR_APPENDING_TRANSFORMER_FLAGS=
### @usage: UBERJAR_APPENDING_TRANSFORMER(Resource)
###
### Add AppendingTransformer for UBERJAR() java programs
###
### Parameters:
### - Resource - Resource name
###
### @see: [UBERJAR](#macro_UBERJAR)
macro UBERJAR_APPENDING_TRANSFORMER(Resources...) {
    SET_APPEND(UBERJAR_APPENDING_TRANSFORMER_VALUE $ARGS_DELIM $Resources)
    SET_APPEND(UBERJAR_APPENDING_TRANSFORMER_FLAGS ${pre=--append-transformer :Resources})
}

# tag:java-specific
UBERJAR_SERVICES_RESOURCE_TRANSFORMER_VALUE=
UBERJAR_SERVICES_RESOURCE_TRANSFORMER_FLAG=
### @usage: UBERJAR_SERVICES_RESOURCE_TRANSFORMER()
###
### Add ServicesResourceTransformer for UBERJAR() java programs
###
### @see: [UBERJAR](#macro_UBERJAR)
macro UBERJAR_SERVICES_RESOURCE_TRANSFORMER() {
    SET(UBERJAR_SERVICES_RESOURCE_TRANSFORMER_VALUE yes)
    SET(UBERJAR_SERVICES_RESOURCE_TRANSFORMER_FLAG --service-transformer)
}

# tag:idea-specific
IDEA_EXCLUDE_DIRS_VALUE=
### @usage: IDEA_EXCLUDE_DIRS(<excluded dirs>)
###
### Exclude specified directories from an idea project generated by ya ide idea
### Have no effect on regular build.
macro IDEA_EXCLUDE_DIRS(Args...) {
    SET_APPEND(IDEA_EXCLUDE_DIRS_VALUE $Args)
}

# tag:idea-specific
IDEA_RESOURCE_DIRS_VALUE=
### @usage: IDEA_RESOURCE_DIRS(<additional dirs>)
###
### Set specified resource directories in an idea project generated by ya ide idea
### Have no effect on regular build.
macro IDEA_RESOURCE_DIRS(Args...) {
    SET_APPEND(IDEA_RESOURCE_DIRS_VALUE $Args)
}

# tag:idea-specific
IDEA_MODULE_NAME_VALUE=
### @usage: IDEA_MODULE_NAME(module_name)
###
### Set module name in an idea project generated by ya ide idea
### Have no effect on regular build.
macro IDEA_MODULE_NAME(Name) {
    SET(IDEA_MODULE_NAME_VALUE $Name)
}

# tag:java-specific
JAVAC_FLAGS_VALUE=
_JAVAC_SEM=&& jdk_path $JDK_RESOURCE && jdk_version $JDK_RESOURCE
### @usage: JAVAC_FLAGS(Args...)
###
### Set additional Java compilation flags.
macro JAVAC_FLAGS(Args...) {
    SET_APPEND(JAVAC_OPTS $Args)
    SET_APPEND(JAVAC_FLAGS_VALUE $ARGS_DELIM $Args)
    SET_APPEND(_JAVAC_SEM && javac-flags $Args)
}

# tag:java-specific
ENABLE_PREVIEW_VALUE=
_ENABLE_PREVIEW_SEM=
### @usage: ENABLE_PREVIEW()
###
### Enable java preview features.
macro ENABLE_PREVIEW() {
    SET_APPEND(JVM_ARGS_VALUE --enable-preview)
    SET_APPEND(JAVAC_OPTS --enable-preview --release $JDK_REAL_VERSION)
    SET_APPEND(JAVAC_FLAGS_VALUE --enable-preview --release $JDK_REAL_VERSION)
    SET(ENABLE_PREVIEW_VALUE yes)
    SET(_ENABLE_PREVIEW_SEM && enable_preview)
}

# tag:java-specific
SAVE_JAVAC_GENERATED_SRCS=
SAVE_JAVAC_GENERATED_SRCS_DIR=
SAVE_JAVAC_GENERATED_SRCS_TAR=
when ($SAVE_JAVAC_GENERATED_SRCS) {
    SAVE_JAVAC_GENERATED_SRCS_DIR=${BINDIR}/__javac_generated_srcs__
    SAVE_JAVAC_GENERATED_SRCS_TAR=${BINDIR}/javac_generated.tar
    JAVAC_FLAGS_VALUE+=-s $SAVE_JAVAC_GENERATED_SRCS_DIR
}

# tag:java-specific
MAVEN_EXPORT_GROUP_ID=ru.yandex
### @usage: MAVEN_GROUP_ID(group_id_for_maven_export)
###
### Set maven export group id for JAVA_PROGRAM() and JAVA_LIBRARY().
### Have no effect on regular build.
macro MAVEN_GROUP_ID(Arg, VERSION="no") {
    SET(MAVEN_EXPORT_GROUP_ID $Arg)
    SET(PUBLISH_MAVEN_VERSION $VERSION)
}

# tag:java-specific
ANNOTATION_PROCESSOR_VALUE=
### @usage: ANNOTATION_PROCESSOR(processors...)
###
### The macro is in development.
### Used to specify annotation processors to build JAVA_PROGRAM() and JAVA_LIBRARY().
macro ANNOTATION_PROCESSOR(Args...) {
    SET_APPEND(ANNOTATION_PROCESSOR_VALUE $ARGS_DELIM $Args)
}

EXCLUDE_VALUE=
### @usage: EXCLUDE(prefixes)
###
### Specifies which libraries should be excluded from the classpath.
macro EXCLUDE(Args...) {
    SET_APPEND(EXCLUDE_VALUE $ARGS_DELIM $Args)
}

# tag:java-specific
JAVA_SRCS_VALUE=

### Fill JAVA_SRCS_VALUE for ya ide idea, skip SKIP_CHECK_SRCDIR option
macro _IDEA_JAVA_SRCS_VALUE(RESOURCES?"RESOURCES":"", SKIP_CHECK_SRCDIR?"SKIP_CHECK_SRCDIR":"", Args...) {
    # RESOURCES must be at first position, else ya ide idea will fault
    SET_APPEND(JAVA_SRCS_VALUE $ARGS_DELIM $RESOURCES $Args)
}

### @usage: JAVA_SRCS(srcs)
###
### Specify java source files and resources. A macro can be contained in any of four java modules.
### Keywords:
### 1. SRCDIR x - specify the directory x is performed relatively to search the source code for these patterns. If there is no SRCDIR, the source will be searched relative to the module directory.
### 2. PACKAGE_PREFIX x - use if source paths relative to the SRCDIR does not coincide with the full class names. For example, if all sources of module are in the same package, you can create a directory package/name , and just put the source code in the SRCDIR and specify PACKAGE_PREFIX package.name.
###
### @example:
###  - example/ya.make
###
###        JAVA_PROGRAM()
###            JAVA_SRCS(SRCDIR src/main/java **/*)
###        END()
###
###  - example/src/main/java/ru/yandex/example/HelloWorld.java
###
###        package ru.yandex.example;
###        public class HelloWorld {
###             public static void main(String[] args) {
###                 System.out.println("Hello, World!");
###             }
###        }
###
### Documentation: https://wiki.yandex-team.ru/yatool/java/#javasrcs
macro JAVA_SRCS(Args...) {
    # TODO Use FULL_JAVA_SRCS
    _IDEA_JAVA_SRCS_VALUE($Args)
    # Fill semantic for non-standard sources/resources
    _SEM_JAR_SOURCE_SET($Args)
}

# tag:java-specific
JAVA_ADD_DLLS_VALUE=no
macro ADD_DLLS_TO_JAR() {
    SET(JAVA_ADD_DLLS_VALUE yes)
}

# tag:java-specific
MANAGED_PEERS=
MANAGED_PEERS_CLOSURE=
MANAGEABLE_PEERS_ROOTS=contrib/java
HAS_MANAGEABLE_PEERS=no
PROPAGATES_MANAGEABLE_PEERS=no

# tag:java-specific
DEPENDENCY_MANAGEMENT_VALUE=
### @usage: DEPENDENCY_MANAGEMENT(path/to/lib1 path/to/lib2 ...)
###
### Lock version of the library from the contrib/java at some point, so that all unversioned PEERDIRs to this library refer to the specified version.
###
### For example, if the module has PEERDIR (contrib/java/junit/junit), and
###   1. specifies DEPENDENCY_MANAGEMENT(contrib/java/junit/junit/4.12),
###      the PEERDIR is automatically replaced by contrib/java/junit/junit/4.12;
###   2. doesn't specify DEPENDENCY_MANAGEMENT, PEERDIR automatically replaced
###      with the default from contrib/java/junit/junit/ya.make.
###      These defaults are always there and are supported by maven-import, which puts
###      there the maximum version available in contrib/java.
###
### The property is transitive. That is, if module A PEERDIRs module B, and B has PEERDIR(contrib/java/junit/junit), and this junit was replaced by junit-4.12, then junit-4.12 will come to A through B.
###
### If some module has both DEPENDENCY_MANAGEMENT(contrib/java/junit/junit/4.12) and PERDIR(contrib/java/junit/junit/4.11), the PEERDIR wins.
###
### Documentation: https://wiki.yandex-team.ru/yatool/java/
macro DEPENDENCY_MANAGEMENT(Args...) {
    SET_APPEND(DEPENDENCY_MANAGEMENT_VALUE $ARGS_DELIM $Args)
    _GHOST_PEERDIR($Args)
}

# tag:java-specific
WITH_JDK_VALUE=
### @usage: WITH_JDK()
###
### Add directory with JDK to JAVA_PROGRAM output
macro WITH_JDK() {
    when ($REALPRJNAME == "jdk") {
        _OK=no
    }
    otherwise {
        _PACK_JDK= && ${YMAKE_PYTHON} ${input:"build/scripts/tar_directory.py"} ${tared;output:"jdk.tar"} $WITH_JDK_RESOURCE $WITH_JDK_RESOURCE
        WITH_JDK_VALUE=yes
    }
    ASSERT(_OK [[alt1]]jdk[[rst]] name is prohibited for [[imp]]JAVA_PROGRAM[[rst]] module when [[imp]]WITH_JDK[[rst]] is used, [[imp]]WITH_JDK[[rst]] will be ignored.)
}

# tag:kotlin-specific
WITH_KOTLIN_VALUE=
_WITH_KOTLIN_SEM=
_KOTLIN_VERSION_SEM=
### @usage: WITH_KOTLIN()
###
### Compile kotlin source code in this java module
macro WITH_KOTLIN() {
    SET(WITH_KOTLIN_VALUE yes)
    SET(_WITH_KOTLIN_SEM && with_kotlin)
    SET(_KOTLIN_VERSION_SEM && kotlin_version ${_KOTLIN_VERSION})
}

# tag:kotlin-specific
WITH_KAPT_VALUE=
### @usage: WITH_KAPT()
###
### Use kapt for as annotation processor
macro WITH_KAPT() {
    SET(WITH_KAPT_VALUE yes)
}

# tag:kotlin-specific
KOTLINC_FLAGS_VALUE=-Xjvm-default=all
### @usage: KOTLINC_FLAGS(-flags)
###
### Set additional Kotlin compilation flags.
macro KOTLINC_FLAGS(Args...) {
    SET_APPEND(KOTLINC_OPTS_VALUE $Args)
}

# tag:kotlin-sppecific
WITH_KOTLINC_PLUGIN_ALLOPEN=
_WITH_KOTLINC_PLUGIN_ALLOPEN_SEM=
macro _WITH_KOTLINC_ALLOPEN(Options...) {
    SET_APPEND(KOTLINC_OPTS_VALUE ${pre=-P plugin\:org.jetbrains.kotlin.allopen\::Options})
    SET(WITH_KOTLINC_PLUGIN_ALLOPEN yes)
    SET(_WITH_KOTLINC_PLUGIN_ALLOPEN_SEM && with_kotlinc_plugin_allopen default $Options)
}

# tag:kotlin-specific
### @usage: WITH_KOTLINC_ALLOPEN(-flags)
###
### Enable allopen kotlin compiler plugin https://kotlinlang.org/docs/all-open-plugin.html
macro WITH_KOTLINC_ALLOPEN(HEAD, TAIL...) {
    _WITH_KOTLINC_ALLOPEN($HEAD $TAIL)
}


# tag:kotlin-specific
WITH_KOTLINC_PLUGIN_LOMBOK=
_WITH_KOTLINC_PLUGIN_LOMBOK_SEM=
### @usage: WITH_KOTLINC_LOMBOK(-flags)
###
### Enable lombok kotlin compiler plugin https://kotlinlang.org/docs/lombok.html
macro WITH_KOTLINC_LOMBOK(Options...) {
    SET_APPEND(KOTLINC_OPTS_VALUE ${pre=-P plugin\:org.jetbrains.kotlin.lombok\::Options})
    SET(WITH_KOTLINC_PLUGIN_LOMBOK yes)
    SET(_WITH_KOTLINC_PLUGIN_LOMBOK_SEM && with_kotlinc_plugin_lombok default $Options)
}

# tag:kotlin-specific
WITH_KOTLINC_PLUGIN_NOARG=
_WITH_KOTLINC_PLUGIN_NOARG_SEM=
### @usage: WITH_KOTLINC_NOARG(-flags)
###
### Enable noarg kotlin compiler plugin https://kotlinlang.org/docs/no-arg-plugin.html
macro WITH_KOTLINC_NOARG(Options...) {
    SET_APPEND(KOTLINC_OPTS_VALUE ${pre=-P plugin\:org.jetbrains.kotlin.noarg\::Options})
    SET(WITH_KOTLINC_PLUGIN_NOARG yes)
    SET(_WITH_KOTLINC_PLUGIN_NOARG_SEM && with_kotlinc_plugin_noarg default $Options)
}

# tag:kotlin-specific
WITH_KOTLINC_PLUGIN_SERIALIZATION=
_WITH_KOTLINC_PLUGIN_SERIALIZATION_SEM=
### @usage: WITH_KOTLINC_SERIALIZATION()
###
### Enable serialization kotlin compiler plugin https://kotlinlang.org/docs/serialization.html
macro WITH_KOTLINC_SERIALIZATION() {
    SET(WITH_KOTLINC_PLUGIN_SERIALIZATION yes)
    SET(_WITH_KOTLINC_PLUGIN_SERIALIZATION_SEM && with_kotlinc_plugin_serialization default)
}

# tag:kotlin-specific
WITH_KOTLINC_PLUGIN_DETEKT=
_WITH_KOTLINC_PLUGIN_DETEKT_SEM=
### @usage: WITH_KOTLINC_DETEKT(-flags)
###
### Enable detekt kotlin compiler plugin https://detekt.dev/docs/gettingstarted/compilerplugin/
macro WITH_KOTLINC_DETEKT(Options...) {
    SET_APPEND(KOTLINC_OPTS_VALUE ${pre=-P plugin\:detekt-compiler-plugin\::Options})
    SET(WITH_KOTLINC_PLUGIN_DETEKT yes)
    SET(_WITH_KOTLINC_PLUGIN_DETEKT_SEM && with_kotlinc_plugin_detekt)
}


# tag:kotlin-specific
### Also search for _KAPT_OPTS and change version there
_KOTLIN_VERSION=1.9.24
KOTLIN_VERSION=1.9.24
KOTLIN_BOM_FILE=${ARCADIA_ROOT}/contrib/java/org/jetbrains/kotlin/kotlin-bom/1.9.24/ya.dependency_management.inc
DETEKT_VERSION=1.23.7

_KOTLIN_SEM= \
    ${_WITH_KOTLIN_SEM} \
    ${_KOTLIN_VERSION_SEM} \
    ${_WITH_KOTLIN_GRPC_SEM} \
    ${_WITH_KOTLINC_PLUGIN_ALLOPEN_SEM} \
    ${_WITH_KOTLINC_PLUGIN_LOMBOK_SEM} \
    ${_WITH_KOTLINC_PLUGIN_NOARG_SEM} \
    ${_WITH_KOTLINC_PLUGIN_SERIALIZATION_SEM} \
    ${_WITH_KOTLINC_PLUGIN_DETEKT_SEM}


_JAVA_PROTO_GRPC_SEM=
when ($_GRPC_ENABLED == "yes") {
    _JAVA_PROTO_GRPC_SEM= && proto_grpc && proto_grpc_version ${JAVA_GRPC_VERSION}
}

_JAVA_PROTO_NAMESPACE_SEM=
when ($PROTO_NAMESPACE != "") {
    _JAVA_PROTO_NAMESPACE_SEM= && proto_namespace $PROTO_NAMESPACE
}

_JAVA_PROTO_SEM= \
    ${_JAVA_PROTO_NAMESPACE_SEM} \
    && proto_compiler_version ${JAVA_PROTO_COMPILER_VERSION} \
    && proto_runtime_version ${JAVA_PROTO_RUNTIME_VERSION} \
    && proto_common_version ${JAVA_PROTO_COMMON_VERSION} \
    ${_JAVA_PROTO_GRPC_SEM}

# tag:java-specific
DIRECT_DEPS_ONLY_VALUE=
### @usage: DIRECT_DEPS_ONLY
###
### Add direct PEERDIR's only in java compile classpath
macro DIRECT_DEPS_ONLY() {
    SET(DIRECT_DEPS_ONLY_VALUE yes)
}

# tag:java-specific
JAVA_EXTERNAL_DEPENDENCIES_VALUE=
### @usage: JAVA_EXTERNAL_DEPENDENCIES(file1 file2 ...)
###
### Add non-source java external build dependency (like lombok config file)
macro JAVA_EXTERNAL_DEPENDENCIES(Args...) {
    SET_APPEND(JAVA_EXTERNAL_DEPENDENCIES_VALUE $Args)
}

# tag:java-specific
JAVA_CLASSPATH_CMD_TYPE_VALUE=

# tag:java-specific
### @usage:TEST_JAVA_CLASSPATH_CMD_TYPE(Type)
### Available types: MANIFEST(default), COMMAND_FILE, LIST
### Method for passing a classpath value to a java command line
### MANIFEST via empty jar file with manifest that contains Class-Path attribute
### COMMAND_FILE via @command_file
### LIST via flat args
macro TEST_JAVA_CLASSPATH_CMD_TYPE(Type) {
    SET(JAVA_CLASSPATH_CMD_TYPE_VALUE $Type)
}

# tag:java-specific
IGNORE_JAVA_DEPENDENCIES_CONFIGURATION=no
JAVA_DEPENDENCIES_CONFIGURATION_VALUE=

# tag:java-specific
### @usage: JAVA_DEPENDENCIES_CONFIGURATION(Vetos...)
### Validate contrib/java dependencies
### Valid arguments
### FORBID_DIRECT_PEERDIRS - fail when module have direct PEERDIR (with version) (non-transitive)
### FORBID_CONFLICT - fail when module have resolved without DEPENDENCY_MANAGEMENT version conflict (transitive)
### FORBID_CONFLICT_DM - fail when module have resolved with DEPENDENCY_MANAGEMENT version conflict (transitive)
### FORBID_CONFLICT_DM_RECENT - like FORBID_CONFLICT_DM but fail only when dependency have more recent version than specified in DEPENDENCY_MANAGEMENT
### REQUIRE_DM - all dependencies must be specified in DEPENDENCY_MANAGEMENT (transitive)
macro JAVA_DEPENDENCIES_CONFIGURATION(Args...) {
    SET_APPEND(JAVA_DEPENDENCIES_CONFIGURATION_VALUE $Args)
}

# tag:java-specific
# TODO(DEVTOOLS-6901): remove this variable when there are no more references to it in jbuild
JAVA_FORBIDDEN_LIBRARIES_VALUE=

# tag:java-specific
JAR_INCLUDE_FILTER_VALUE=
JAR_EXCLUDE_FILTER_VALUE=

# tag:java-specific
### @usage: JAR_INCLUDE(Filters...)
### Filter .jar file content: keep only matched files
### * and ** patterns are supported (like JAVA_SRCS)
macro JAR_INCLUDE(Filters...) {
    SET_APPEND(JAR_INCLUDE_FILTER_VALUE $Filters)
}

# tag:java-specific
### @usage: JAR_EXCLUDE(Filters...)
### Filter .jar file content: remove matched files
### * and ** patterns are supported (like JAVA_SRCS)
macro JAR_EXCLUDE(Filters...) {
    SET_APPEND(JAR_EXCLUDE_FILTER_VALUE $Filters)
}

# tag:java-specific
_COMPILE_JSRC=${cwd:ARCADIA_BUILD_ROOT} $YMAKE_PYTHON ${input:"build/scripts/compile_jsrc.py"} --input $AUTO_INPUT --output $TARGET --prefix $BINDIR ${hide;kv:"p JC"} ${hide;kv:"pc light-blue"} ${hide;kv:"show_out"}

# tag:java-specific
COMPILE_JSRC_MF=$_COMPILE_JSRC && $GENERATE_MF

# tag:java-specific tag:internal
### @usage: JSRC_LIBRARY() # internal
module JSRC_LIBRARY: _BARE_UNIT {
    .CMD=COMPILE_JSRC_MF
    .EXTS=.java
    .PEERDIR_POLICY=as_include
    .FINAL_TARGET=no
    .ALIASES=SRCS=FILES
    PEERDIR_TAGS=JAVA JAVA_PROTO JAVA_PROTO_FROM_SCHEMA JAVA_FBS JAVA_IDL
    MODULE_TYPE=LIBRARY
    SET(MODULE_SUFFIX .jsrc)
    SET(DONT_RESOLVE_INCLUDES yes)
    SET(NEED_PLATFORM_PEERDIRS no)
    SET(MODULE_LANG JAVA)

    NO_RUNTIME()
}

# tag:java-specific
JAVA_PROGRAM_CP_USE_COMMAND_FILE=yes
when ($JDK_REAL_VERSION == "8") {
    JAVA_PROGRAM_CP_USE_COMMAND_FILE=no
}

# tag:kotlin-specific
KOTLIN_JVM_TARGET=
when ($JDK_REAL_VERSION == "8") {
    KOTLIN_JVM_TARGET=1.8
}
elsewhen ($JDK_REAL_VERSION == "22") {
    # remove when kotlin starts supporting jdk21 bytecode
    # see also devtools/ya/jbuild/gen/actions/idea.py
    KOTLIN_JVM_TARGET=21
}
elsewhen ($JDK_REAL_VERSION == "23") {
    # remove when kotlin starts supporting jdk21 bytecode
    # see also devtools/ya/jbuild/gen/actions/idea.py
    KOTLIN_JVM_TARGET=21
}
otherwise {
    KOTLIN_JVM_TARGET=$JDK_REAL_VERSION
}

# tag:java-specific tag:internal
### @usage: _JDK_VERSION_INTERNAL(Version) #internal
###
### Specify JDK version for module
macro _JDK_VERSION_INTERNAL(Arg) {
    .SEM=required_jdk $Arg ${hide;output:"JdkVersionFakeProp.java"}
    SET(JDK_REAL_VERSION $Arg)
    _JDK_VERSION_MACRO_CHECK($Arg)
}

# tag:java-specific
### @usage: JDK_VERSION(Version)
###
### Specify JDK version for module
macro JDK_VERSION(Arg) {
    _JDK_VERSION_INTERNAL($Arg)
}

# tag:java-specific
### @usage: DEFAULT_JDK_VERSION(Version)
###
### Specify JDK version for module, can be overridden by setting the JDK_VERSION variable
macro DEFAULT_JDK_VERSION(Arg) {
    _SET_FIRST_VALUE(_JDK_VERSION $JDK_VERSION $Arg)
    _JDK_VERSION_INTERNAL($_JDK_VERSION)
}

# tag:java-specific
# local jdk and tools
USE_SYSTEM_JDK=
USE_SYSTEM_UBERJAR=
USE_SYSTEM_ERROR_PRONE=

# tag:kotlin-specific
_USE_KTLINT_OLD=no

# tag:kotlin-specific
### @usage: USE_KTLINT_OLD()
### Marks that need use the old version of ktlint
macro USE_KTLINT_OLD() {
    ENABLE(_USE_KTLINT_OLD)
}

# tag:kotlin-specific
_KTLINT_BASELINE_FILE=

# tag:kotlin-specific
### @usage: KTLINT_BASELINE_FILE(ktlint-baseline.xml "https://st.yandex-team.ru/REMOVE-BASELINE-1") # deprecated
### Path to baseline file for ktlint test and ticket to fix all ktlint warnings in file and then remove it
macro KTLINT_BASELINE_FILE(File, Ticket) {
    SET(_KTLINT_BASELINE_FILE $File)
}

# tag:kotlin-specific
_WITH_YA_1931=no

# tag:kotlin-specific
### @usage: WITH_YA_1931()
### Interim macro to temporarily remove ALL_SRCDIRS from being added to ktlint test sources.
macro WITH_YA_1931() {
    MESSAGE(WARNING Some files in this project have style errors that were not caught by prior ktlint runs. Remove WITH_YA_1931 macro to see them.)
    ENABLE(_WITH_YA_1931)
}