Merge branch 'master' into size-benchmarks
diff --git a/benchmarks/BUILD b/benchmarks/BUILD
index 3e06fff..a937acc 100644
--- a/benchmarks/BUILD
+++ b/benchmarks/BUILD
@@ -3,6 +3,11 @@
     "upb_proto_library",
     "upb_proto_reflection_library",
 )
+load(
+    ":build_defs.bzl",
+    "tmpl_cc_binary",
+    "cc_lite_proto_library",
+)
 
 licenses(["notice"])
 
@@ -58,3 +63,79 @@
         "@com_google_protobuf//:protobuf",
     ],
 )
+
+# Size benchmarks.
+
+SIZE_BENCHMARKS = {
+    "empty": "Empty",
+    "descriptor": "FileDescriptorSet",
+    "100_msgs": "Message99",
+}
+
+py_binary(
+    name = "gen_benchmark_proto",
+    srcs = ["gen_benchmark_proto.py"],
+)
+
+genrule(
+    name = "gen_100_msgs",
+    tools = [":gen_benchmark_proto"],
+    outs = ["100_msgs.proto"],
+    cmd = "$(execpath :gen_benchmark_proto) $@",
+)
+
+[(
+proto_library(
+    name = k + "_proto",
+    srcs = [k + ".proto"],
+),
+upb_proto_library(
+    name = k + "_upb_proto",
+    deps = [":" + k + "_proto"],
+),
+cc_proto_library(
+    name = k + "_cc_proto",
+    deps = [":" + k + "_proto"],
+),
+tmpl_cc_binary(
+    name = k + "_upb_binary",
+    testonly = 1,
+    srcs = ["upb_binary.c.tmpl"],
+    replacements = {
+        "PROTO": "upb_benchmark_" + v,
+        "INCLUDE": "benchmarks/" + k + ".upb.h",
+    },
+    deps = [
+        ":" + k + "_upb_proto",
+    ],
+),
+tmpl_cc_binary(
+    name = k + "_protobuf_binary",
+    testonly = 1,
+    srcs = ["protobuf_binary.cc.tmpl"],
+    replacements = {
+        "PROTO": "upb_benchmark::" + v,
+        "INCLUDE": "benchmarks/" + k + ".pb.h",
+    },
+    deps = [
+        ":" + k + "_cc_proto",
+    ],
+),
+cc_lite_proto_library(
+    srcs = [k + ".proto"],
+    outs = [k + "_lite.proto"],
+    name = k + "_cc_lite_proto",
+),
+tmpl_cc_binary(
+    name = k + "_lite_protobuf_binary",
+    testonly = 1,
+    srcs = ["protobuf_binary.cc.tmpl"],
+    replacements = {
+        "PROTO": "upb_benchmark::" + v,
+        "INCLUDE": "benchmarks/" + k + "_lite.pb.h",
+    },
+    deps = [
+        ":" + k + "_cc_lite_proto",
+    ],
+)) for k, v in SIZE_BENCHMARKS.items()]
+
diff --git a/benchmarks/build_defs.bzl b/benchmarks/build_defs.bzl
new file mode 100644
index 0000000..402a523
--- /dev/null
+++ b/benchmarks/build_defs.bzl
@@ -0,0 +1,44 @@
+
+def tmpl_cc_binary(name, srcs, replacements = [], **kwargs):
+    if len(srcs) != 1:
+        fail("Currently srcs must have exactly 1 element")
+    src = srcs[0]
+    if not src.endswith(".tmpl"):
+        fail("srcs of tmpl_cc_binary must end with .tmpl")
+    outs = [name + "_" + src[:-5]]
+    sed_cmds = ["s,{},{},g".format(k, v) for k, v in replacements.items()]
+    cmd = "sed -e '{}' $< > $@".format("; ".join(sed_cmds))
+
+    native.genrule(
+        name = name + "_gen_srcs",
+        srcs = [src],
+        outs = outs,
+        cmd = cmd,
+    )
+
+    native.cc_binary(
+        name = name,
+        srcs = outs,
+        **kwargs,
+    )
+
+def cc_lite_proto_library(name, srcs, outs):
+    if len(srcs) != 1:
+        fail("Currently srcs must have exactly 1 element")
+
+    native.genrule(
+        name = name + "_gen_proto",
+        srcs = srcs,
+        outs = outs,
+        cmd = "cp $< $@ && chmod a+w $@ && echo 'option optimize_for = LITE_RUNTIME;' >> $@",
+    )
+
+    native.proto_library(
+        name = name + "_proto",
+        srcs = outs,
+    )
+
+    native.cc_proto_library(
+        name = name,
+        deps = [":" + name + "_proto"],
+    )
diff --git a/benchmarks/empty.proto b/benchmarks/empty.proto
new file mode 100644
index 0000000..bcccaf9
--- /dev/null
+++ b/benchmarks/empty.proto
@@ -0,0 +1,6 @@
+
+syntax = "proto3";
+
+package upb_benchmark;
+
+message Empty {}
diff --git a/benchmarks/protobuf_binary.cc.tmpl b/benchmarks/protobuf_binary.cc.tmpl
new file mode 100644
index 0000000..139ad74
--- /dev/null
+++ b/benchmarks/protobuf_binary.cc.tmpl
@@ -0,0 +1,10 @@
+
+#include "INCLUDE"
+
+char buf[1];
+
+int main() {
+  PROTO proto;
+  proto.ParseFromArray(buf, 1);
+  proto.SerializeToArray(buf, 1);
+}
diff --git a/benchmarks/small.proto b/benchmarks/small.proto
new file mode 100644
index 0000000..cfc59c2
--- /dev/null
+++ b/benchmarks/small.proto
@@ -0,0 +1,35 @@
+// A small proto, for measuring the overhead of a minimal use of
+// protocol buffers.
+
+syntax = "proto3";
+
+option optimize_for = LITE_RUNTIME;
+option cc_enable_arenas = true;
+
+package upb_benchmark;
+
+message Person {
+  string name = 1;
+  int32 id = 2;  // Unique ID number for this person.
+  string email = 3;
+
+  enum PhoneType {
+    MOBILE = 0;
+    HOME = 1;
+    WORK = 2;
+  }
+
+  message PhoneNumber {
+    string number = 1;
+    PhoneType type = 2;
+  }
+
+  repeated PhoneNumber phones = 4;
+
+  int64 last_updated = 5;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+  repeated Person people = 1;
+}
diff --git a/benchmarks/upb_binary.c.tmpl b/benchmarks/upb_binary.c.tmpl
new file mode 100644
index 0000000..6f2904b
--- /dev/null
+++ b/benchmarks/upb_binary.c.tmpl
@@ -0,0 +1,12 @@
+
+#include "INCLUDE"
+
+char buf[1];
+
+int main() {
+  upb_arena *arena = upb_arena_new();
+  size_t size;
+  PROTO *proto = PROTO_parse(buf, 1, arena);
+  PROTO_serialize(proto, arena, &size);
+  return 0;
+}