diff --git a/build/intellij.idea.community.build.iml b/build/intellij.idea.community.build.iml
index 08ba75f534f1..db295323b245 100644
--- a/build/intellij.idea.community.build.iml
+++ b/build/intellij.idea.community.build.iml
@@ -8,6 +8,8 @@
+
+
diff --git a/build/protobuf/getprotoc.bat b/build/protobuf/getprotoc.bat
new file mode 100644
index 000000000000..24a8e5bd2562
--- /dev/null
+++ b/build/protobuf/getprotoc.bat
@@ -0,0 +1,47 @@
+:: Usage:
+:: @echo off
+:: for /f %%i in ('git.exe rev-parse --show-toplevel') do set "toplevel=%%~fi"
+:: call "%toplevel%\build\protobuf\getprotoc.bat"
+:: @echo on
+@echo off
+
+if not defined PROTOC_VERSION set PROTOC_VERSION=3.5.1
+
+if not defined PROTOC_BIN_DIR (
+ for /f %%i in ('git.exe rev-parse --show-toplevel') do set "toplevel=%%~fi"
+ set "PROTOC_BIN_DIR=%toplevel%\build\protobuf\bin"
+)
+if not exist "%PROTOC_BIN_DIR%" mkdir "%PROTOC_BIN_DIR%"
+
+if not defined PROTOC_CACHE_DIR (
+ set "PROTOC_CACHE_DIR=%PROTOC_BIN_DIR%\..\cache"
+)
+if not exist "%PROTOC_CACHE_DIR%" mkdir "%PROTOC_CACHE_DIR%"
+
+call:getprotoc || goto :exit
+
+set PATH=%PROTOC_BIN_DIR%;%PATH%
+
+:exit
+exit /b %errorlevel%
+
+
+:getprotoc
+ set "_protoc_zip_name=protoc-%PROTOC_VERSION%-win32.zip"
+ if not exist "%PROTOC_CACHE_DIR%\%_protoc_zip_name%" (
+ curl.exe -L --output "%PROTOC_CACHE_DIR%\%_protoc_zip_name%" ^
+ "https://github.com/protocolbuffers/protobuf/releases/download/v%PROTOC_VERSION%/%_protoc_zip_name%" || goto :exit
+ )
+
+ set "_protoc_exe=%PROTOC_BIN_DIR%\protoc.exe"
+ if exist "%_protoc_exe%.tmp" del "%_protoc_exe%.tmp"
+ if exist "%_protoc_exe%" move /y "%_protoc_exe%" "%_protoc_exe%.tmp" >nul
+
+ tar.exe --strip-components 1 -xf "%PROTOC_CACHE_DIR%\%_protoc_zip_name%" -C "%PROTOC_BIN_DIR%" bin/protoc.exe || (
+ if exist "%_protoc_exe%.tmp" move /y "%_protoc_exe%.tmp" "%_protoc_exe%" >nul
+ del "%PROTOC_CACHE_DIR%\%_protoc_zip_name%"
+ goto :exit
+ )
+
+ if exist "%_protoc_exe%.tmp" del "%_protoc_exe%.tmp"
+goto :eof
diff --git a/build/protobuf/getprotoc.sh b/build/protobuf/getprotoc.sh
new file mode 100644
index 000000000000..d9505478a399
--- /dev/null
+++ b/build/protobuf/getprotoc.sh
@@ -0,0 +1,37 @@
+# Usage: . "$(git rev-parse --show-toplevel)/build/protobuf/getprotoc.sh"
+PROTOC_VERSION=${PROTOC_VERSION:-3.5.1}
+
+PROTOC_BIN_DIR="${PROTOC_BIN_DIR:-$(git rev-parse --show-toplevel)/build/protobuf/bin}"
+PROTOC_CACHE_DIR="${PROTOC_CACHE_DIR:-$(dirname "$PROTOC_BIN_DIR")/cache}"
+
+mkdir -p "$PROTOC_BIN_DIR"
+mkdir -p "$PROTOC_CACHE_DIR"
+
+case "$(uname -s)" in
+ Darwin) PROTOC_OS_NAME="osx-$(uname -m)" ;;
+ Linux) PROTOC_OS_NAME="linux-$(uname -m)" ;;
+ *) echo "unrecognized operating system"; exit 1 ;;
+esac
+
+getprotoc() {
+ _protoc_zip_name="protoc-$PROTOC_VERSION-$PROTOC_OS_NAME.zip"
+ test -f "$PROTOC_CACHE_DIR/$_protoc_zip_name" || \
+ wget -O "$PROTOC_CACHE_DIR/$_protoc_zip_name" \
+ "https://github.com/protocolbuffers/protobuf/releases/download/v$_protoc_version/$_protoc_zip_name"
+
+ _protoc_exe="$PROTOC_BIN_DIR/protoc"
+ rm -f "$_protoc_exe.tmp"
+ test -f "$_protoc_exe" && mv -f "$_protoc_exe" "$_protoc_exe.tmp"
+
+ tar --strip-components 1 -xf "$PROTOC_CACHE_DIR/$_protoc_zip_name" -C "$PROTOC_BIN_DIR" bin/protoc || (
+ test -f "$_protoc_exe.tmp" && mv -f "$_protoc_exe.tmp" "$_protoc_exe"
+ rm -f "$PROTOC_CACHE_DIR/$_protoc_zip_name"
+ exit 1
+ )
+
+ rm -f "$_protoc_exe.tmp"
+}
+
+getprotoc
+
+export PATH="$PROTOC_BIN_DIR:$PATH"
diff --git a/jps/jps-builders-6/proto/gen_proto.bat b/jps/jps-builders-6/proto/gen_proto.bat
index 511694ed4eec..777ce4da7042 100644
--- a/jps/jps-builders-6/proto/gen_proto.bat
+++ b/jps/jps-builders-6/proto/gen_proto.bat
@@ -1 +1,6 @@
-call protoc -I=. --java_out=../src --java_opt=annotate_code javac_remote_proto.proto
\ No newline at end of file
+@echo off
+for /f %%i in ('git.exe rev-parse --show-toplevel') do set "toplevel=%%~fi"
+call "%toplevel%\build\protobuf\getprotoc.bat"
+@echo on
+
+protoc -I=. --java_out=../src --java_opt=annotate_code javac_remote_proto.proto
diff --git a/jps/jps-builders-6/proto/gen_proto.sh b/jps/jps-builders-6/proto/gen_proto.sh
index e72f3b123cbc..2bdc2cd94dff 100755
--- a/jps/jps-builders-6/proto/gen_proto.sh
+++ b/jps/jps-builders-6/proto/gen_proto.sh
@@ -1 +1,4 @@
-protoc -I=. --java_out=../src --java_opt=annotate_code javac_remote_proto.proto
\ No newline at end of file
+#!/usr/bin/env sh
+. "$(git rev-parse --show-toplevel)/build/protobuf/getprotoc.sh"
+
+protoc -I=. --java_out=../src --java_opt=annotate_code javac_remote_proto.proto
diff --git a/jps/jps-builders/proto/gen_proto.bat b/jps/jps-builders/proto/gen_proto.bat
index 88fcdc21fe0c..ff46c4d05ae1 100644
--- a/jps/jps-builders/proto/gen_proto.bat
+++ b/jps/jps-builders/proto/gen_proto.bat
@@ -1 +1,6 @@
-call protoc -I=. --java_out=../src --java_opt=annotate_code cmdline_remote_proto.proto
\ No newline at end of file
+@echo off
+for /f %%i in ('git.exe rev-parse --show-toplevel') do set "toplevel=%%~fi"
+call "%toplevel%\build\protobuf\getprotoc.bat"
+@echo on
+
+protoc -I=. --java_out=../src --java_opt=annotate_code cmdline_remote_proto.proto
diff --git a/jps/jps-builders/proto/gen_proto.sh b/jps/jps-builders/proto/gen_proto.sh
index a354c085edff..efe6bf2e8ecd 100755
--- a/jps/jps-builders/proto/gen_proto.sh
+++ b/jps/jps-builders/proto/gen_proto.sh
@@ -1 +1,4 @@
-protoc -I=. --java_out=../src --java_opt=annotate_code cmdline_remote_proto.proto
\ No newline at end of file
+#!/bin/sh
+. "$(git rev-parse --show-toplevel)/build/protobuf/getprotoc.sh"
+
+protoc -I=. --java_out=../src --java_opt=annotate_code cmdline_remote_proto.proto