Created an amalgamation without handlers, and fixed some bugs. (#283)

* Created amalgamation with upb_msg but no handlers.

* Bugfix for upb_array_resize().

* Renamed "lite" amalgamation to "core", to avoid confusion.

Traditionally "lite" has meant "without reflection", but here we
mean it as "without handlers-based code."

* Build fixes from CI tests.

* Removed some more C++-style comments.

* Fix for out-of-order statements.
diff --git a/BUILD b/BUILD
index 4e83463..b9a3ceb 100644
--- a/BUILD
+++ b/BUILD
@@ -681,6 +681,33 @@
     }),
 )
 
+upb_amalgamation(
+    name = "gen_core_amalgamation",
+    prefix = "core-",
+    outs = [
+        "core-upb.c",
+        "core-upb.h",
+    ],
+    amalgamator = ":amalgamate",
+    libs = [
+        ":upb",
+        ":descriptor_upbproto",
+        ":reflection",
+        ":port",
+        ":json",
+    ],
+)
+
+cc_library(
+    name = "core_amalgamation",
+    srcs = ["core-upb.c"],
+    hdrs = ["core-upb.h"],
+    copts = select({
+        ":windows": [],
+        "//conditions:default": COPTS,
+    }),
+)
+
 # Lua ##########################################################################
 
 cc_library(
diff --git a/bazel/build_defs.bzl b/bazel/build_defs.bzl
index 7544e12..c51aded 100644
--- a/bazel/build_defs.bzl
+++ b/bazel/build_defs.bzl
@@ -135,7 +135,7 @@
     ctx.actions.run(
         inputs = inputs,
         outputs = ctx.outputs.outs,
-        arguments = [ctx.bin_dir.path + "/"] + [f.path for f in srcs] + ["-I" + root for root in _get_real_roots(inputs)],
+        arguments = [ctx.bin_dir.path + "/", ctx.attr.prefix] + [f.path for f in srcs] + ["-I" + root for root in _get_real_roots(inputs)],
         progress_message = "Making amalgamation",
         executable = ctx.executable.amalgamator,
     )
@@ -147,6 +147,9 @@
             executable = True,
             cfg = "host",
         ),
+        "prefix": attr.string(
+            default = "",
+        ),
         "libs": attr.label_list(aspects = [_file_list_aspect]),
         "outs": attr.output_list(),
     },
diff --git a/tools/amalgamate.py b/tools/amalgamate.py
index dff1bc3..b244eff 100755
--- a/tools/amalgamate.py
+++ b/tools/amalgamate.py
@@ -11,14 +11,14 @@
   return match.groups()[0] if match else None
 
 class Amalgamator:
-  def __init__(self, output_path):
+  def __init__(self, output_path, prefix):
     self.include_paths = ["."]
     self.included = set(["upb/port_def.inc", "upb/port_undef.inc"])
-    self.output_h = open(output_path + "upb.h", "w")
-    self.output_c = open(output_path + "upb.c", "w")
+    self.output_h = open(output_path + prefix + "upb.h", "w")
+    self.output_c = open(output_path + prefix + "upb.c", "w")
 
     self.output_c.write("/* Amalgamated source file */\n")
-    self.output_c.write('#include "upb.h"\n')
+    self.output_c.write('#include "%supb.h"\n' % (prefix))
     self.output_c.write(open("upb/port_def.inc").read())
 
     self.output_h.write("/* Amalgamated source file */\n")
@@ -73,10 +73,11 @@
 # ---- main ----
 
 output_path = sys.argv[1]
-amalgamator = Amalgamator(output_path)
+prefix = sys.argv[2]
+amalgamator = Amalgamator(output_path, prefix)
 files = []
 
-for arg in sys.argv[2:]:
+for arg in sys.argv[3:]:
   arg = arg.strip()
   if arg.startswith("-I"):
     amalgamator.add_include_path(arg[2:])
diff --git a/tools/make_cmakelists.py b/tools/make_cmakelists.py
index 76e3ee1..5fe7a65 100755
--- a/tools/make_cmakelists.py
+++ b/tools/make_cmakelists.py
@@ -38,7 +38,7 @@
   def cc_library(self, **kwargs):
     if kwargs["name"] == "amalgamation" or kwargs["name"] == "upbc_generator":
       return
-    if kwargs["name"] == "lupb":
+    if kwargs["name"] == "core_amalgamation" or kwargs["name"] == "lupb":
       return
     files = kwargs.get("srcs", []) + kwargs.get("hdrs", [])
     found_files = []
diff --git a/upb/json_decode.c b/upb/json_decode.c
index bb4337c..4b19b43 100644
--- a/upb/json_decode.c
+++ b/upb/json_decode.c
@@ -405,7 +405,9 @@
 
     switch (ch) {
       case '"': {
-        upb_strview ret = {buf, end - buf};
+        upb_strview ret;
+        ret.data = buf;
+        ret.size = end - buf;
         return ret;
       }
       case '\\':
@@ -413,7 +415,7 @@
         if (*d->ptr == 'u') {
           d->ptr++;
           if (buf_end - end < 4) {
-            // Allow space for maximum-sized code point (4 bytes).
+            /* Allow space for maximum-sized code point (4 bytes). */
             jsondec_resize(d, &buf, &end, &buf_end);
           }
           end += jsondec_unicode(d, end);
@@ -888,7 +890,8 @@
 
   if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) {
     /* JSON "null" indicates a default value, so no need to set anything. */
-    return jsondec_null(d);
+    jsondec_null(d);
+    return;
   }
 
   preserved = d->debug_field;
@@ -1005,7 +1008,7 @@
   if (str.size < 20) goto malformed;
 
   {
-    // 1972-01-01T01:00:00
+    /* 1972-01-01T01:00:00 */
     int year = jsondec_tsdigits(d, &ptr, 4, "-");
     int mon = jsondec_tsdigits(d, &ptr, 2, "-");
     int day = jsondec_tsdigits(d, &ptr, 2, "T");
@@ -1019,7 +1022,7 @@
   nanos.int32_val = jsondec_nanos(d, &ptr, end);
 
   {
-    // [+-]08:00 or Z
+    /* [+-]08:00 or Z */
     int ofs = 0;
     bool neg = false;
 
@@ -1062,7 +1065,7 @@
   const char *ptr = str.data;
   const char *end = ptr + str.size;
 
-  // "3.000000001s", "3s", etc.
+  /* "3.000000001s", "3s", etc. */
   ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val);
   nanos.int32_val = jsondec_nanos(d, &ptr, end);
 
@@ -1311,10 +1314,10 @@
   if (pre_type_data) {
     size_t len = pre_type_end - pre_type_data + 1;
     char *tmp = upb_arena_malloc(d->arena, len);
-    memcpy(tmp, pre_type_data, len - 1);
-    tmp[len - 1] = '}';
     const char *saved_ptr = d->ptr;
     const char *saved_end = d->end;
+    memcpy(tmp, pre_type_data, len - 1);
+    tmp[len - 1] = '}';
     d->ptr = tmp;
     d->end = tmp + len;
     d->is_first = true;
diff --git a/upb/msg.c b/upb/msg.c
index a211f1a..a1acaa4 100644
--- a/upb/msg.c
+++ b/upb/msg.c
@@ -149,19 +149,10 @@
   return arr;
 }
 
-static bool resize_array(upb_array *arr, size_t size, upb_arena *arena) {
-  if (size > arr->size && !_upb_array_realloc(arr, size, arena)) {
-    return false;
-  }
-
-  arr->len = size;
-  return true;
-}
-
 void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
                                  upb_fieldtype_t type, upb_arena *arena) {
   upb_array *arr = getorcreate_array(arr_ptr, type, arena);
-  return arr && resize_array(arr, size, arena) ? _upb_array_ptr(arr) : NULL;
+  return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr) : NULL;
 }
 
 bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
@@ -171,7 +162,7 @@
   int lg2 = _upb_fieldtype_to_sizelg2[type];
   char *data;
 
-  if (!arr || !resize_array(arr, elem + 1, arena)) return false;
+  if (!arr || !_upb_array_resize(arr, elem + 1, arena)) return false;
 
   data = _upb_array_ptr(arr);
   memcpy(data + (elem << lg2), value, 1 << lg2);
diff --git a/upb/msg.h b/upb/msg.h
index 2109348..1fc302f 100644
--- a/upb/msg.h
+++ b/upb/msg.h
@@ -142,6 +142,19 @@
 bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
                                 upb_fieldtype_t type, upb_arena *arena);
 
+UPB_INLINE bool _upb_array_reserve(upb_array *arr, size_t size,
+                                   upb_arena *arena) {
+  if (arr->size < size) return _upb_array_realloc(arr, size, arena);
+  return true;
+}
+
+UPB_INLINE bool _upb_array_resize(upb_array *arr, size_t size,
+                                  upb_arena *arena) {
+  if (!_upb_array_reserve(arr, size, arena)) return false;
+  arr->len = size;
+  return true;
+}
+
 UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs,
                                            size_t *size) {
   const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*);
@@ -285,7 +298,7 @@
   upb_value tabval;
   upb_strview k = _upb_map_tokey(key, key_size);
   bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval);
-  if (ret) {
+  if (ret && val) {
     _upb_map_fromvalue(tabval, val, val_size);
   }
   return ret;
@@ -296,8 +309,8 @@
   it.t = &map->table;
   it.index = *iter;
   upb_strtable_next(&it);
-  if (upb_strtable_done(&it)) return NULL;
   *iter = it.index;
+  if (upb_strtable_done(&it)) return NULL;
   return (void*)str_tabent(&it);
 }
 
diff --git a/upb/reflection.c b/upb/reflection.c
index 190bde5..446dc7e 100644
--- a/upb/reflection.c
+++ b/upb/reflection.c
@@ -254,10 +254,8 @@
   return true;
 }
 
-/* Resizes the array to the given size, reallocating if necessary, and returns a
- * pointer to the new array elements. */
 bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) {
-  return _upb_array_realloc(arr, size, arena);
+  return _upb_array_resize(arr, size, arena);
 }
 
 /** upb_map *******************************************************************/
@@ -289,6 +287,14 @@
   return _upb_map_next(map, iter);
 }
 
+bool upb_mapiter_done(const upb_map *map, size_t iter) {
+  upb_strtable_iter i;
+  UPB_ASSERT(iter != UPB_MAP_BEGIN);
+  i.t = &map->table;
+  i.index = iter;
+  return upb_strtable_done(&i);
+}
+
 /* Returns the key and value for this entry of the map. */
 upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) {
   upb_strtable_iter i;
diff --git a/upb/reflection.h b/upb/reflection.h
index c55fe4a..5371ca7 100644
--- a/upb/reflection.h
+++ b/upb/reflection.h
@@ -143,6 +143,11 @@
 /* Advances to the next entry.  Returns false if no more entries are present. */
 bool upb_mapiter_next(const upb_map *map, size_t *iter);
 
+/* Returns true if the iterator still points to a valid entry, or false if the
+ * iterator is past the last element. It is an error to call this function with
+ * UPB_MAP_BEGIN (you must call next() at least once first). */
+bool upb_mapiter_done(const upb_map *map, size_t iter);
+
 /* Returns the key and value for this entry of the map. */
 upb_msgval upb_mapiter_key(const upb_map *map, size_t iter);
 upb_msgval upb_mapiter_value(const upb_map *map, size_t iter);
diff --git a/upb/table.c b/upb/table.c
index 21f8fcf..c5ca3ac 100644
--- a/upb/table.c
+++ b/upb/table.c
@@ -243,7 +243,7 @@
 static size_t next(const upb_table *t, size_t i) {
   do {
     if (++i >= upb_table_size(t))
-      return SIZE_MAX;
+      return SIZE_MAX - 1;  /* Distinct from -1. */
   } while(upb_tabent_isempty(&t->entries[i]));
 
   return i;