Implement bazel build

The implemented Bazel build is 100% compatible to Buck build.

Test Plan:

  $ bazel build :all
  $ VERBOSE=1 ./mvn.sh install
  $ VERBOSE=1 ./mvn.sh deploy

Bug: Issue 5336
Change-Id: I13e0f78570e4063e8b4f8d13deff328c682eefef
diff --git a/.gitignore b/.gitignore
index 3dab871..8069d28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,8 @@
 /.settings
 /.apt_generated
 /buck-out
+/bazel-bin
+/bazel-genfiles
+/bazel-out
+/bazel-prolog-cafe
+/bazel-testlogs
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..2ca8ea4
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,258 @@
+load("@com_googlesource_gerrit_bazlets//tools/maven:package.bzl", "maven_package")
+load("//:prolog.bzl", "pl2j")
+
+VERSION = "1.4.2"
+
+SRC = "java/com/googlecode/prolog_cafe/"
+
+REPL = [
+    SRC + "builtin/PRED_$write_toString_2.java",
+]
+
+IO = [
+    SRC + "builtin/PRED_close_2.java",
+    SRC + "builtin/PRED_flush_output_1.java",
+    SRC + "builtin/PRED_open_4.java",
+    SRC + "builtin/PRED_read_line_2.java",
+    SRC + "builtin/PRED_tab_2.java",
+]
+
+genrule(
+    name = "all",
+    srcs = [
+        ":cafeteria_deploy.jar",
+        ":compiler",
+        ":runtime_deploy.jar",
+    ],
+    outs = ["all.zip"],
+    cmd = " && ".join([
+        "TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)",
+        "ROOT=$$PWD",
+        "cp $(SRCS) $$TMP",
+        "cd $$TMP",
+        "zip -qr $$ROOT/$@ .",
+    ]),
+)
+
+java_binary(
+    name = "runtime",
+    main_class = "Dummy",
+    runtime_deps = [
+        ":builtin",
+        ":lang",
+    ],
+)
+
+java_library(
+    name = "lang",
+    srcs = glob(
+        [
+            SRC + "exceptions/*.java",
+            SRC + "lang/*.java",
+        ],
+        exclude = REPL,
+    ),
+)
+
+#java_library(
+#  name = 'builtin',
+#  srcs = glob([SRC + 'builtin/*.java'], exclude = REPL + IO) +
+#  [
+##    ':builtin_srcs',
+##    ':system_srcs',
+#  ],
+#  deps = [':lang'],
+#)
+
+# TODO(davido): Fix that mess when this major Bazel bug is fixed:
+# https://github.com/bazelbuild/bazel/issues/374
+# That why I left the original :builtin rule from Buck, so that
+# you can feel my pain, to emulate the glob with zip, to hide
+# the files that contain '$' from Bazel.
+genrule(
+    name = "builtin_srcjar",
+    outs = ["builtin.srcjar"],
+    cmd = " && ".join([
+        "TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)",
+        "ROOT=$$PWD",
+        "cd java",
+        "zip -q $$ROOT/$@ com/googlecode/prolog_cafe/builtin/*.java",
+        "zip -qd $$ROOT/$@ com/googlecode/prolog_cafe/builtin/PRED_\$$write_toString_2.java %s" % " ".join([s[5:] for s in IO]),
+    ]),
+    local = 1,
+)
+
+java_library(
+    name = "builtin",
+    srcs = [
+        ":builtin_srcjar",
+        ":builtin_srcs",
+        ":system_srcs",
+    ],
+    deps = [":lang"],
+)
+
+pl2j(
+    name = "builtin_srcs",
+    src = "src/builtin/builtins.pl",
+    out = "builtins.srcjar",
+)
+
+pl2j(
+    name = "system_srcs",
+    src = "src/builtin/system.pl",
+    out = "system.srcjar",
+)
+
+java_library(
+    name = "io",
+    srcs = IO + [":io_srcs"],
+    deps = [
+        ":builtin",
+        ":lang",
+    ],
+)
+
+pl2j(
+    name = "io_srcs",
+    src = "src/builtin/io.pl",
+    out = "io.srcjar",
+)
+
+java_library(
+    name = "compiler",
+    srcs = glob([SRC + "compiler/**/*.java"]) + [
+        ":pl2am_srcs",
+        ":am2j_srcs",
+    ],
+    deps = [
+        ":builtin",
+        ":io",
+        ":lang",
+    ],
+)
+
+pl2j(
+    name = "pl2am_srcs",
+    src = "src/compiler/pl2am.pl",
+    out = "pl2am.srcjar",
+)
+
+pl2j(
+    name = "am2j_srcs",
+    src = "src/compiler/am2j.pl",
+    out = "am2j.srcjar",
+)
+
+java_binary(
+    name = "plc",
+    main_class = "com.googlecode.prolog_cafe.compiler.Compiler",
+    runtime_deps = [":compiler"],
+)
+
+java_binary(
+    name = "cafeteria",
+    main_class = "com.googlecode.prolog_cafe.repl.PrologMain",
+    runtime_deps = [":cafeteria_lib"],
+)
+
+# TODO(davido): Same as above
+genrule(
+    name = "cafeteria_lib_srcjar",
+    outs = ["cafeteria_lib.srcjar"],
+    cmd = " && ".join([
+        "TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)",
+        "ROOT=$$PWD",
+        "cd java",
+        "zip -q $$ROOT/$@ com/googlecode/prolog_cafe/repl/*.java com/googlecode/prolog_cafe/builtin/PRED_\$$write_toString_2.java",
+    ]),
+    local = 1,
+)
+
+java_library(
+    name = "cafeteria_lib",
+    srcs = [
+        ":cafeteria_lib.srcjar",
+        ":cafeteria_srcs",
+    ],
+    deps = [
+        ":builtin",
+        ":io",
+        ":lang",
+    ],
+)
+
+pl2j(
+    name = "cafeteria_srcs",
+    src = "src/builtin/cafeteria.pl",
+    out = "cafeteria.srcjar",
+)
+
+# TODO(davido): Same as above
+genrule(
+    name = "runtime_src",
+    srcs = [
+        "src/builtin/builtins.pl",
+        "src/builtin/system.pl",
+    ],
+    outs = ["runtime_sources.zip"],
+    cmd = " && ".join([
+        "TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)",
+        "ROOT=$$PWD",
+        "cp $(SRCS) $$TMP/",
+        "cd $$TMP",
+        "unzip -q $$ROOT/$(location :builtin_srcjar)",
+        "zip -qr $$ROOT/$@ .",
+    ]),
+    tools = [":builtin_srcjar"],
+)
+
+java_library(
+    name = "io_src",
+    resources = IO + ["src/builtin/io.pl"],
+)
+
+java_library(
+    name = "compiler_src",
+    resources = glob([SRC + "compiler/**/*.java"]) + [
+        "src/compiler/pl2am.pl",
+        "src/compiler/am2j.pl",
+    ],
+)
+
+# TODO(davido): Same as above
+genrule(
+    name = "cafeteria_src",
+    srcs = [
+        "src/builtin/cafeteria.pl",
+    ],
+    outs = ["cafeteria_sources.zip"],
+    cmd = " && ".join([
+        "TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)",
+        "ROOT=$$PWD",
+        "cp $(SRCS) $$TMP/",
+        "cd $$TMP",
+        "unzip -q $$ROOT/$(location :cafeteria_lib_srcjar)",
+        "zip -qr $$ROOT/$@ .",
+    ]),
+    tools = [":cafeteria_lib_srcjar"],
+)
+
+maven_package(
+    src = {
+        "prolog-cafeteria": ":cafeteria_src",
+        "prolog-compiler": ":compiler_src",
+        "prolog-io": ":io_src",
+        "prolog-runtime": ":runtime_src",
+    },
+    group = "com.googlecode.prolog-cafe",
+    jar = {
+        "prolog-cafeteria": ":cafeteria_lib",
+        "prolog-compiler": ":compiler",
+        "prolog-io": ":io",
+        "prolog-runtime": ":runtime_deploy.jar",
+    },
+    repository = "gerrit-maven-repository",
+    url = "gs://gerrit-maven/",
+    version = VERSION,
+)
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..7cca9aa
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,8 @@
+workspace(name = "prolog_cafe")
+
+load("//:bazlets.bzl", "load_bazlets")
+
+load_bazlets(
+    commit = "0f87babe07a555425d829c6e7951e296e9e24579",
+    #    local_path = "/home/<user>/projects/bazlets"
+)
diff --git a/bazlets.bzl b/bazlets.bzl
new file mode 100644
index 0000000..e14e488
--- /dev/null
+++ b/bazlets.bzl
@@ -0,0 +1,17 @@
+NAME = "com_googlesource_gerrit_bazlets"
+
+def load_bazlets(
+    commit,
+    local_path = None
+  ):
+  if not local_path:
+      native.git_repository(
+          name = NAME,
+          remote = "https://gerrit.googlesource.com/bazlets",
+          commit = commit,
+      )
+  else:
+      native.local_repository(
+          name = NAME,
+          path = local_path,
+      )
diff --git a/mvn.sh b/mvn.sh
new file mode 100755
index 0000000..ed9c213
--- /dev/null
+++ b/mvn.sh
@@ -0,0 +1,56 @@
+#!/bin/bash -e
+
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [[ "$#" != "1" ]] ; then
+  cat <<EOF
+Usage: run "$0 COMMAND" from the top of your workspace,
+where COMMAND is one of
+
+  install
+  deploy
+
+Set VERBOSE in the environment to get more information.
+
+EOF
+
+  exit 1
+fi
+
+set -o errexit
+set -o nounset
+
+case "$1" in
+install)
+    command="api_install"
+    ;;
+deploy)
+    command="api_deploy"
+    ;;
+*)
+    echo "unknown command $1"
+    exit 1
+    ;;
+esac
+
+if [[ "${VERBOSE:-x}" != "x" ]]; then
+  set -o xtrace
+fi
+
+bazel build //:gen_${command} || \
+  { echo "bazel failed to build gen_${command}. Use VERBOSE=1 for more info" ; exit 1 ; }
+
+export OUTPUT_BASE=`bazel info output_base`
+./bazel-genfiles/${command}.sh
diff --git a/prolog.bzl b/prolog.bzl
new file mode 100644
index 0000000..b4723ae
--- /dev/null
+++ b/prolog.bzl
@@ -0,0 +1,72 @@
+# Translating Prolog into WAM-based Intermediate Code
+def pl2am(name, src, out):
+  srcs = [
+    'src/compiler/package_fx.pl',
+    'src/compiler/pl2am.pl',
+    'src/builtin/system.pl',
+  ]
+  if not src in srcs:
+    srcs.append(src)
+  native.genrule(
+    name = name,
+    srcs = srcs,
+    cmd = " && ".join([
+      'ROOT=$$PWD',
+      'TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)',
+      'echo "go :- '
+        + 'load_files(['
+          + "'$$ROOT/src/compiler/package_fx.pl',"
+          + "'$$ROOT/src/builtin/system.pl',"
+          + "'$$ROOT/src/compiler/pl2am.pl'"
+        + ']),'
+        + 'pl2am(['
+          + "'$$(basename %s)'," % src
+          + "'$$ROOT/$@',"
+          + '[ed,ac,ie,rc,idx]'
+        + ']).'
+        + '">$$TMP/go.pl',
+      'cd $$(dirname %s)' % src,
+      'swipl --traditional --quiet -g go,halt -t "halt(1)" $$TMP/go.pl',
+    ]),
+    outs = [out],
+  )
+
+# Translating WAM-based Intermediate Code into Java
+def am2j(name, am, out):
+  native.genrule(
+    name = name,
+    srcs = [
+      am,
+      'src/compiler/am2j.pl',
+    ],
+    cmd = " && ".join([
+      'ROOT=$$PWD',
+      'TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)',
+      'echo "go :- '
+        + 'load_files(['
+          + "'src/compiler/am2j.pl'"
+        + ']),'
+        + 'am2j(['
+          + "'$(location %s)'," % am
+          + "'$$TMP/java'"
+        + ']).'
+        + '">$$TMP/go.pl',
+      'mkdir $$TMP/java',
+      'swipl --traditional --quiet -g go,halt -t "halt(1)" $$TMP/go.pl',
+      'cd $$TMP/java',
+      'zip -qr $$ROOT/$@ .',
+    ]),
+    outs = [out],
+  )
+
+def pl2j(name, src, out):
+  pl2am(
+    name = name + '_rule.am',
+    src = src,
+    out = name + '.am',
+  )
+  am2j(
+    name = name,
+    am = ':' + name + '_rule.am',
+    out = out,
+  )