Add upb_MiniTable_FindUnknown depth_limit parameter.
Fix UpbMessageIsEqual IsMap fallthrough.

PiperOrigin-RevId: 522961305
diff --git a/BUILD b/BUILD
index 0985927..24bde07 100644
--- a/BUILD
+++ b/BUILD
@@ -139,6 +139,7 @@
         "upb/string_view.h",
         "upb/upb.h",
         "upb/upb.hpp",
+        "upb/wire/common.h",
         "upb/wire/decode.h",
         "upb/wire/encode.h",
     ],
@@ -880,6 +881,7 @@
         "upb/wire/encode.c",
     ],
     hdrs = [
+        "upb/wire/common.h",
         "upb/wire/common_internal.h",
         "upb/wire/decode.h",
         "upb/wire/decode_fast.h",
diff --git a/python/message.c b/python/message.c
index 753cc74..2fe5126 100644
--- a/python/message.c
+++ b/python/message.c
@@ -36,6 +36,7 @@
 #include "upb/reflection/message.h"
 #include "upb/text/encode.h"
 #include "upb/util/required_fields.h"
+#include "upb/wire/common.h"
 
 static const upb_MessageDef* PyUpb_MessageMeta_GetMsgdef(PyObject* cls);
 static PyObject* PyUpb_MessageMeta_GetAttr(PyObject* self, PyObject* name);
@@ -1254,8 +1255,9 @@
   const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef);
   upb_Arena* arena = PyUpb_Arena_Get(self->arena);
   PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
-  int options =
-      UPB_DECODE_MAXDEPTH(state->allow_oversize_protos ? UINT32_MAX : 100);
+  int options = upb_DecodeOptions_MaxDepth(
+      state->allow_oversize_protos ? UINT16_MAX
+                                   : kUpb_WireFormat_DefaultDepthLimit);
   upb_DecodeStatus status =
       upb_Decode(buf, size, self->ptr.msg, layout, extreg, options, arena);
   Py_XDECREF(bytes);
diff --git a/upb/message/accessors.c b/upb/message/accessors.c
index 2ed872a..c10ffec 100644
--- a/upb/message/accessors.c
+++ b/upb/message/accessors.c
@@ -32,6 +32,7 @@
 #include "upb/collections/map.h"
 #include "upb/message/message.h"
 #include "upb/mini_table/field_internal.h"
+#include "upb/wire/common.h"
 #include "upb/wire/decode.h"
 #include "upb/wire/encode.h"
 #include "upb/wire/eps_copy_input_stream.h"
@@ -83,7 +84,8 @@
 
   // Check unknown fields, if available promote.
   int field_number = ext_table->field.number;
-  upb_FindUnknownRet result = upb_MiniTable_FindUnknown(msg, field_number);
+  upb_FindUnknownRet result = upb_MiniTable_FindUnknown(
+      msg, field_number, kUpb_WireFormat_DefaultDepthLimit);
   if (result.status != kUpb_FindUnknown_Ok) {
     return kUpb_GetExtension_NotPresent;
   }
@@ -134,7 +136,8 @@
     return kUpb_GetExtensionAsBytes_Ok;
   }
   int field_number = ext_table->field.number;
-  upb_FindUnknownRet result = upb_MiniTable_FindUnknown(msg, field_number);
+  upb_FindUnknownRet result = upb_MiniTable_FindUnknown(
+      msg, field_number, upb_DecodeOptions_GetMaxDepth(encode_options));
   if (result.status != kUpb_FindUnknown_Ok) {
     return kUpb_GetExtensionAsBytes_NotPresent;
   }
@@ -153,8 +156,8 @@
 }
 
 upb_FindUnknownRet upb_MiniTable_FindUnknown(const upb_Message* msg,
-                                             uint32_t field_number) {
-  const int depth_limit = 100;  // TODO: this should be a parameter
+                                             uint32_t field_number,
+                                             int depth_limit) {
   size_t size;
   upb_FindUnknownRet ret;
 
@@ -204,7 +207,8 @@
   upb_UnknownToMessageRet ret;
   ret.status = kUpb_UnknownToMessage_Ok;
   do {
-    unknown = upb_MiniTable_FindUnknown(msg, field->number);
+    unknown = upb_MiniTable_FindUnknown(
+        msg, field->number, upb_DecodeOptions_GetMaxDepth(decode_options));
     switch (unknown.status) {
       case kUpb_FindUnknown_Ok: {
         const char* unknown_data = unknown.ptr;
@@ -250,7 +254,8 @@
   // Find all unknowns with given field number and parse.
   upb_FindUnknownRet unknown;
   do {
-    unknown = upb_MiniTable_FindUnknown(msg, field->number);
+    unknown = upb_MiniTable_FindUnknown(
+        msg, field->number, upb_DecodeOptions_GetMaxDepth(decode_options));
     if (unknown.status == kUpb_FindUnknown_Ok) {
       upb_UnknownToMessageRet ret = upb_MiniTable_ParseUnknownMessage(
           unknown.ptr, unknown.len, mini_table,
@@ -314,7 +319,8 @@
   // Find all unknowns with given field number and parse.
   upb_FindUnknownRet unknown;
   while (1) {
-    unknown = upb_MiniTable_FindUnknown(msg, field->number);
+    unknown = upb_MiniTable_FindUnknown(
+        msg, field->number, upb_DecodeOptions_GetMaxDepth(decode_options));
     if (unknown.status != kUpb_FindUnknown_Ok) break;
     upb_UnknownToMessageRet ret = upb_MiniTable_ParseUnknownMessage(
         unknown.ptr, unknown.len, map_entry_mini_table,
diff --git a/upb/message/accessors.h b/upb/message/accessors.h
index 6b56e58..74ca1f2 100644
--- a/upb/message/accessors.h
+++ b/upb/message/accessors.h
@@ -708,7 +708,8 @@
 
 // Finds first occurrence of unknown data by tag id in message.
 upb_FindUnknownRet upb_MiniTable_FindUnknown(const upb_Message* msg,
-                                             uint32_t field_number);
+                                             uint32_t field_number,
+                                             int depth_limit);
 
 typedef enum {
   kUpb_UnknownToMessage_Ok,
diff --git a/upb/message/accessors_test.cc b/upb/message/accessors_test.cc
index d299acd..a0dece4 100644
--- a/upb/message/accessors_test.cc
+++ b/upb/message/accessors_test.cc
@@ -33,6 +33,8 @@
 
 #include "upb/message/accessors.h"
 
+#include <string>
+
 #include "gtest/gtest.h"
 #include "google/protobuf/test_messages_proto2.upb.h"
 #include "google/protobuf/test_messages_proto3.upb.h"
@@ -44,6 +46,7 @@
 #include "upb/mini_table/field_internal.h"
 #include "upb/test/test.upb.h"
 #include "upb/upb.h"
+#include "upb/wire/common.h"
 #include "upb/wire/decode.h"
 
 namespace {
@@ -163,7 +166,7 @@
       0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int32(msg));
 
   EXPECT_EQ(0, upb_Message_GetInt32(msg, optional_int32_field, 0));
-  upb_Message_SetInt32(msg, optional_int32_field, kTestInt32, NULL);
+  upb_Message_SetInt32(msg, optional_int32_field, kTestInt32, nullptr);
   EXPECT_EQ(true, upb_Message_HasField(msg, optional_int32_field));
   EXPECT_EQ(kTestInt32, upb_Message_GetInt32(msg, optional_int32_field, 0));
   EXPECT_EQ(
@@ -176,7 +179,7 @@
   EXPECT_EQ(
       0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint32(msg));
   EXPECT_EQ(0, upb_Message_GetUInt32(msg, optional_uint32_field, 0));
-  upb_Message_SetUInt32(msg, optional_uint32_field, kTestUInt32, NULL);
+  upb_Message_SetUInt32(msg, optional_uint32_field, kTestUInt32, nullptr);
   EXPECT_EQ(kTestUInt32, upb_Message_GetUInt32(msg, optional_uint32_field, 0));
   EXPECT_EQ(
       kTestUInt32,
@@ -197,14 +200,14 @@
 
   EXPECT_EQ(
       0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(msg));
-  upb_Message_SetInt64(msg, optional_int64_field, -1, NULL);
+  upb_Message_SetInt64(msg, optional_int64_field, -1, nullptr);
   EXPECT_EQ(
       -1, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(msg));
   EXPECT_EQ(-1, upb_Message_GetInt64(msg, optional_int64_field, 0));
 
   EXPECT_EQ(
       0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(msg));
-  upb_Message_SetUInt64(msg, optional_uint64_field, kTestUInt64, NULL);
+  upb_Message_SetUInt64(msg, optional_uint64_field, kTestUInt64, nullptr);
   EXPECT_EQ(
       kTestUInt64,
       protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(msg));
@@ -239,7 +242,7 @@
       protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_string(
           msg));
   upb_Message_SetString(msg, optional_string_field,
-                        upb_StringView_FromString(kTestStr2), NULL);
+                        upb_StringView_FromString(kTestStr2), nullptr);
   EXPECT_EQ(true, upb_Message_HasField(msg, optional_string_field));
   EXPECT_EQ(
       true,
@@ -261,8 +264,8 @@
       find_proto2_field(kFieldOptionalNestedMessage);
 
   const upb_Message* test_message =
-      upb_Message_GetMessage(msg, optional_message_field, NULL);
-  EXPECT_EQ(NULL, test_message);
+      upb_Message_GetMessage(msg, optional_message_field, nullptr);
+  EXPECT_EQ(nullptr, test_message);
 
   EXPECT_EQ(false, upb_Message_HasField(msg, optional_message_field));
 
@@ -277,8 +280,8 @@
 
   // Read back using mini table API.
   const upb_Message* sub_message =
-      upb_Message_GetMessage(msg, optional_message_field, NULL);
-  EXPECT_EQ(true, sub_message != NULL);
+      upb_Message_GetMessage(msg, optional_message_field, nullptr);
+  EXPECT_EQ(true, sub_message != nullptr);
 
   const upb_MiniTableField* nested_message_a_field =
       upb_MiniTable_FindFieldByNumber(
@@ -288,14 +291,15 @@
 
   upb_Message_ClearField(msg, optional_message_field);
   EXPECT_EQ(
-      NULL,
+      nullptr,
       protobuf_test_messages_proto2_TestAllTypesProto2_optional_nested_message(
           msg));
   EXPECT_EQ(false, upb_Message_HasField(msg, optional_message_field));
 
   upb_Message* new_nested_message =
       protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_new(arena);
-  upb_Message_SetInt32(new_nested_message, nested_message_a_field, 123, NULL);
+  upb_Message_SetInt32(new_nested_message, nested_message_a_field, 123,
+                       nullptr);
   upb_Message_SetMessage(
       msg, &protobuf_test_messages_proto2_TestAllTypesProto2_msg_init,
       optional_message_field, new_nested_message);
@@ -306,7 +310,7 @@
   EXPECT_EQ(
       true,
       protobuf_test_messages_proto2_TestAllTypesProto2_optional_nested_message(
-          msg) != NULL);
+          msg) != nullptr);
   EXPECT_EQ(true, upb_Message_HasField(msg, optional_message_field));
   EXPECT_EQ(123,
             upb_Message_GetInt32(mutable_message, nested_message_a_field, 0));
@@ -328,8 +332,8 @@
                                                                       &len);
   // Test Get/Set Array values, validate with C API.
   EXPECT_EQ(0, len);
-  EXPECT_EQ(NULL, arr);
-  EXPECT_EQ(NULL, upb_Message_GetArray(msg, repeated_int32_field));
+  EXPECT_EQ(nullptr, arr);
+  EXPECT_EQ(nullptr, upb_Message_GetArray(msg, repeated_int32_field));
   protobuf_test_messages_proto2_TestAllTypesProto2_resize_repeated_int32(
       msg, 10, arena);
   int32_t* mutable_values =
@@ -361,7 +365,7 @@
       protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg,
                                                                       &len);
   EXPECT_EQ(0, len);
-  EXPECT_EQ(true, zero_length_array != NULL);
+  EXPECT_EQ(true, zero_length_array != nullptr);
 
   upb_Arena_Free(arena);
 }
@@ -407,11 +411,13 @@
                                                 arena);
 
   upb_FindUnknownRet result = upb_MiniTable_FindUnknown(
-      base_msg, upb_test_ModelExtension1_model_ext_ext.field.number);
+      base_msg, upb_test_ModelExtension1_model_ext_ext.field.number,
+      kUpb_WireFormat_DefaultDepthLimit);
   EXPECT_EQ(kUpb_FindUnknown_Ok, result.status);
 
   result = upb_MiniTable_FindUnknown(
-      base_msg, upb_test_ModelExtension2_model_ext_ext.field.number);
+      base_msg, upb_test_ModelExtension2_model_ext_ext.field.number,
+      kUpb_WireFormat_DefaultDepthLimit);
   EXPECT_EQ(kUpb_FindUnknown_NotPresent, result.status);
 
   upb_Arena_Free(arena);
@@ -639,21 +645,22 @@
   int32_t val = upb_Message_GetInt32(
       msg, upb_MiniTable_FindFieldByNumber(mini_table, 4), 0);
   EXPECT_EQ(val, 11);
-  upb_FindUnknownRet unknown = upb_MiniTable_FindUnknown(msg, 5);
+  upb_FindUnknownRet unknown =
+      upb_MiniTable_FindUnknown(msg, 5, kUpb_WireFormat_DefaultDepthLimit);
   EXPECT_EQ(unknown.status, kUpb_FindUnknown_Ok);
   // Update mini table and promote unknown to a message.
   EXPECT_TRUE(upb_MiniTable_SetSubMessage(
       mini_table, (upb_MiniTableField*)&mini_table->fields[1],
       &upb_test_ModelWithExtensions_msg_init));
-  const int decode_options =
-      UPB_DECODE_MAXDEPTH(100);  // UPB_DECODE_ALIAS disabled.
+  const int decode_options = upb_DecodeOptions_MaxDepth(
+      kUpb_WireFormat_DefaultDepthLimit);  // UPB_DECODE_ALIAS disabled.
   upb_UnknownToMessageRet promote_result =
       upb_MiniTable_PromoteUnknownToMessage(
           msg, mini_table, &mini_table->fields[1],
           &upb_test_ModelWithExtensions_msg_init, decode_options, arena);
   EXPECT_EQ(promote_result.status, kUpb_UnknownToMessage_Ok);
   const upb_Message* promoted_message =
-      upb_Message_GetMessage(msg, &mini_table->fields[1], NULL);
+      upb_Message_GetMessage(msg, &mini_table->fields[1], nullptr);
   EXPECT_EQ(upb_test_ModelWithExtensions_random_int32(
                 (upb_test_ModelWithExtensions*)promoted_message),
             12);
@@ -687,15 +694,16 @@
   EXPECT_EQ(val, 123);
 
   // Check that we have repeated field data in an unknown.
-  upb_FindUnknownRet unknown = upb_MiniTable_FindUnknown(msg, 6);
+  upb_FindUnknownRet unknown =
+      upb_MiniTable_FindUnknown(msg, 6, kUpb_WireFormat_DefaultDepthLimit);
   EXPECT_EQ(unknown.status, kUpb_FindUnknown_Ok);
 
   // Update mini table and promote unknown to a message.
   EXPECT_TRUE(upb_MiniTable_SetSubMessage(
       mini_table, (upb_MiniTableField*)&mini_table->fields[2],
       &upb_test_ModelWithExtensions_msg_init));
-  const int decode_options =
-      UPB_DECODE_MAXDEPTH(100);  // UPB_DECODE_ALIAS disabled.
+  const int decode_options = upb_DecodeOptions_MaxDepth(
+      kUpb_WireFormat_DefaultDepthLimit);  // UPB_DECODE_ALIAS disabled.
   upb_UnknownToMessage_Status promote_result =
       upb_MiniTable_PromoteUnknownToMessageArray(
           msg, &mini_table->fields[2], &upb_test_ModelWithExtensions_msg_init,
@@ -734,23 +742,25 @@
   upb_MiniTable* mini_table = CreateMiniTableWithEmptySubTablesForMaps(arena);
   upb_MiniTable* map_entry_mini_table = CreateMapEntryMiniTable(arena);
   upb_Message* msg = _upb_Message_New(mini_table, arena);
-  upb_DecodeStatus decode_status = upb_Decode(serialized, serialized_size, msg,
-                                              mini_table, nullptr, 0, arena);
+  const int decode_options =
+      upb_DecodeOptions_MaxDepth(kUpb_WireFormat_DefaultDepthLimit);
+  upb_DecodeStatus decode_status =
+      upb_Decode(serialized, serialized_size, msg, mini_table, nullptr,
+                 decode_options, arena);
   EXPECT_EQ(decode_status, kUpb_DecodeStatus_Ok);
   int32_t val = upb_Message_GetInt32(
       msg, upb_MiniTable_FindFieldByNumber(mini_table, 1), 0);
   EXPECT_EQ(val, 123);
 
   // Check that we have map data in an unknown.
-  upb_FindUnknownRet unknown = upb_MiniTable_FindUnknown(msg, 3);
+  upb_FindUnknownRet unknown =
+      upb_MiniTable_FindUnknown(msg, 3, kUpb_WireFormat_DefaultDepthLimit);
   EXPECT_EQ(unknown.status, kUpb_FindUnknown_Ok);
 
   // Update mini table and promote unknown to a message.
   EXPECT_TRUE(upb_MiniTable_SetSubMessage(
       mini_table, (upb_MiniTableField*)&mini_table->fields[1],
       map_entry_mini_table));
-  const int decode_options =
-      UPB_DECODE_MAXDEPTH(100);  // UPB_DECODE_ALIAS disabled.
   upb_UnknownToMessage_Status promote_result =
       upb_MiniTable_PromoteUnknownToMap(msg, mini_table, &mini_table->fields[1],
                                         decode_options, arena);
diff --git a/upb/wire/common.h b/upb/wire/common.h
new file mode 100644
index 0000000..c35b575
--- /dev/null
+++ b/upb/wire/common.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009-2021, Google LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Google LLC nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UPB_WIRE_COMMON_H_
+#define UPB_WIRE_COMMON_H_
+
+// Must be last.
+#include "upb/port/def.inc"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define kUpb_WireFormat_DefaultDepthLimit 100
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // UPB_WIRE_COMMON_H_
diff --git a/upb/wire/decode.c b/upb/wire/decode.c
index ed2ee98..c2ab7e0 100644
--- a/upb/wire/decode.c
+++ b/upb/wire/decode.c
@@ -35,6 +35,7 @@
 #include "upb/mini_table/common.h"
 #include "upb/mini_table/enum_internal.h"
 #include "upb/port/atomic.h"
+#include "upb/wire/common.h"
 #include "upb/wire/common_internal.h"
 #include "upb/wire/decode_internal.h"
 #include "upb/wire/encode.h"
@@ -1301,7 +1302,7 @@
 
   decoder.extreg = extreg;
   decoder.unknown = NULL;
-  decoder.depth = depth ? depth : 64;
+  decoder.depth = depth ? depth : kUpb_WireFormat_DefaultDepthLimit;
   decoder.end_group = DECODE_NOGROUP;
   decoder.options = (uint16_t)options;
   decoder.missing_required = false;
diff --git a/upb/wire/decode.h b/upb/wire/decode.h
index 95c831e..b2198f9 100644
--- a/upb/wire/decode.h
+++ b/upb/wire/decode.h
@@ -66,13 +66,19 @@
   kUpb_DecodeOption_CheckRequired = 2,
 };
 
-#define UPB_DECODE_MAXDEPTH(depth) ((depth) << 16)
+UPB_INLINE uint32_t upb_DecodeOptions_MaxDepth(uint16_t depth) {
+  return (uint32_t)depth << 16;
+}
+
+UPB_INLINE uint16_t upb_DecodeOptions_GetMaxDepth(uint32_t options) {
+  return options >> 16;
+}
 
 // Enforce an upper bound on recursion depth.
 UPB_INLINE int upb_Decode_LimitDepth(uint32_t decode_options, uint32_t limit) {
-  uint32_t max_depth = decode_options >> 16;
+  uint32_t max_depth = upb_DecodeOptions_GetMaxDepth(decode_options);
   if (max_depth > limit) max_depth = limit;
-  return (max_depth << 16) | (decode_options & 0xffff);
+  return upb_DecodeOptions_MaxDepth(max_depth) | (decode_options & 0xffff);
 }
 
 typedef enum {
diff --git a/upb/wire/encode.c b/upb/wire/encode.c
index ef3b4ad..ef931a7 100644
--- a/upb/wire/encode.c
+++ b/upb/wire/encode.c
@@ -35,6 +35,7 @@
 #include "upb/collections/map_sorter_internal.h"
 #include "upb/message/extension_internal.h"
 #include "upb/mini_table/sub_internal.h"
+#include "upb/wire/common.h"
 #include "upb/wire/common_internal.h"
 #include "upb/wire/swap_internal.h"
 #include "upb/wire/types.h"
@@ -622,7 +623,7 @@
   e.buf = NULL;
   e.limit = NULL;
   e.ptr = NULL;
-  e.depth = depth ? depth : 64;
+  e.depth = depth ? depth : kUpb_WireFormat_DefaultDepthLimit;
   e.options = options;
   _upb_mapsorter_init(&e.sorter);