diff --git a/tests/bindings/lua/BUILD b/tests/bindings/lua/BUILD index 8834feb8ff..a065b1df55 100644 --- a/tests/bindings/lua/BUILD +++ b/tests/bindings/lua/BUILD @@ -16,6 +16,7 @@ cc_test( data = [ "test_upb.lua", ":descriptor_proto_lua", + ":empty_proto_lua", ":test_messages_proto2_proto_lua", ":test_messages_proto3_proto_lua", ":test_proto_lua", @@ -49,6 +50,11 @@ lua_proto_library( deps = ["@com_google_protobuf//:descriptor_proto"], ) +lua_proto_library( + name = "empty_proto_lua", + deps = ["@com_google_protobuf//:empty_proto"], +) + lua_proto_library( name = "test_messages_proto3_proto_lua", testonly = 1, diff --git a/tests/bindings/lua/test_upb.lua b/tests/bindings/lua/test_upb.lua index 0f4a3d2725..292aaf164c 100644 --- a/tests/bindings/lua/test_upb.lua +++ b/tests/bindings/lua/test_upb.lua @@ -5,6 +5,7 @@ local upb_test = require "tests.bindings.lua.test_pb" local test_messages_proto3 = require "google.protobuf.test_messages_proto3_pb" local test_messages_proto2 = require "google.protobuf.test_messages_proto2_pb" local descriptor = require "google.protobuf.descriptor_pb" +local empty = require "google.protobuf.empty_pb" if _VERSION >= 'Lua 5.2' then _ENV = lunit.module("testupb", "seeall") @@ -664,6 +665,21 @@ function test_descriptor_error() assert_nil(symtab:lookup_msg("ABC")) end +function test_encode_skipunknown() + -- Test that upb.ENCODE_SKIPUNKNOWN does not encode unknown fields. + local msg = test_messages_proto3.TestAllTypesProto3{ + optional_int32 = 10, + optional_uint32 = 20, + optional_int64 = 30, + } + local serialized = upb.encode(msg) + assert_true(#serialized > 0) + local empty_with_unknown = upb.decode(empty.Empty, serialized) + assert_true(#upb.encode(empty_with_unknown) > 0) + print(upb.encode(empty_with_unknown, upb.ENCODE_SKIPUNKNOWN)) + assert_true(#upb.encode(empty_with_unknown, {upb.ENCODE_SKIPUNKNOWN}) == 0) +end + function test_gc() local top = test_messages_proto3.TestAllTypesProto3() local n = 100 diff --git a/upb/bindings/lua/msg.c b/upb/bindings/lua/msg.c index 0c4c35f2c4..792d5f8229 100644 --- a/upb/bindings/lua/msg.c +++ b/upb/bindings/lua/msg.c @@ -1030,6 +1030,7 @@ void lupb_msg_registertypes(lua_State *L) { lupb_setfieldi(L, "TXTENC_NOSORT", UPB_TXTENC_NOSORT); lupb_setfieldi(L, "ENCODE_DETERMINISTIC", UPB_ENCODE_DETERMINISTIC); + lupb_setfieldi(L, "ENCODE_SKIPUNKNOWN", UPB_ENCODE_SKIPUNKNOWN); lupb_cacheinit(L); } diff --git a/upb/encode.c b/upb/encode.c index c1fe02decb..294e1248ba 100644 --- a/upb/encode.c +++ b/upb/encode.c @@ -408,15 +408,16 @@ static void encode_scalarfield(upb_encstate *e, const char *msg, static void encode_message(upb_encstate *e, const char *msg, const upb_msglayout *m, size_t *size) { size_t pre_len = e->limit - e->ptr; - const char *unknown; - size_t unknown_size; const upb_msglayout_field *f = &m->fields[m->field_count]; const upb_msglayout_field *first = &m->fields[0]; - unknown = upb_msg_getunknown(msg, &unknown_size); + if ((e->options & UPB_ENCODE_SKIPUNKNOWN) == 0) { + size_t unknown_size; + const char *unknown = upb_msg_getunknown(msg, &unknown_size); - if (unknown) { - encode_bytes(e, unknown, unknown_size); + if (unknown) { + encode_bytes(e, unknown, unknown_size); + } } while (f != first) { diff --git a/upb/encode.h b/upb/encode.h index 8ff51ab626..ef8c761472 100644 --- a/upb/encode.h +++ b/upb/encode.h @@ -22,6 +22,9 @@ enum { * If your proto contains maps, the encoder will need to malloc()/free() * memory during encode. */ UPB_ENCODE_DETERMINISTIC = 1, + + /* When set, unknown fields are not printed. */ + UPB_ENCODE_SKIPUNKNOWN = 2, }; char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,