~bigbes/tarantool

tarantool-protobuf

a6eebdb3698c166bfb1618023e6ce85b0f7911fd — Eugene Blikh 3 months ago feecf8e
codegen: local counter per repeated field on decode

Replaces `list[#list + 1] = val` with `_n_<fname> = _n_<fname> + 1;
list[_n_<fname>] = val` in every generated M.X_decode repeated-field
append site. One counter local per repeated non-map field, declared at
function entry. Counters survive across loop iterations so out-of-order
wire entries for the same field continue past the existing length
without re-scanning.

Profile attributed 6.2% of hello.Person 1KB decode to the `#list + 1`
re-traversal (26-email Person paid 26 list scans per decode).

Bench (Person full decode, msgs/s, median-of-3 vs post-4kj):
1KB +5.0%, 10KB +5.0%, 100KB +7.1%. Encode flat. Tests 745/745.
JIT 37/37, 0 bridges.

beads-tarantool-protobuf-cch
M bench/PERF_LOG.md => bench/PERF_LOG.md +53 -0
@@ 84,6 84,59 @@ macOS arm64.

<!-- Append new entries below this line. Newest at the top. -->

## 2026-05-18 — cch: local counter for repeated-field append

**Task:** [tarantool-protobuf-cch] Decoder: use local counter instead of
`#list` at repeated-field append. Profile attributed 6.2% of Person 1KB
decode time to `list[#list + 1] = val` re-traversing the list per
append (26 emails per Person → 26 re-scans).

**Change:** In `cmd/protoc-gen-tarantool/internal/gen/inline.go`, the
generated `M.X_decode` now declares one counter local per repeated
non-map field at function entry:

```lua
local _n_emails = 0
local _n_lucky_numbers = 0
-- ...
```

Each `list[#list + 1] = val` emit becomes
`_n_emails = _n_emails + 1; list[_n_emails] = val`. Counters survive
across loop iterations, so out-of-order wire entries for the same field
keep appending past the existing length without re-scanning.

Map fields are skipped (hash-keyed, no array index).

**Tests:** 745/745. JIT: 37/37, 0 bridges.

**Bench (Person full, msgs/s, median-of-3 vs post-4kj baseline):**

| size  | dir | post-4kj  | cch       | Δ        |
|-------|-----|-----------|-----------|----------|
| 1KB   | dec | 109,792   | 115,310   | **+5.0%** |
| 10KB  | dec | 15,084    | 15,831    | **+5.0%** |
| 100KB | dec | 1,512     | 1,620     | **+7.1%** |
| 10B   | dec | 2,579,347 | 2,495,633 | -3.2%    |
| 100B  | dec | 2,122,601 | 2,131,196 | +0.4%    |
| 1KB   | enc | 293,367   | 294,691   | +0.5%    |
| 10KB  | enc | 59,390    | 58,684    | -1.2%    |
| 100KB | enc | 6,570     | 6,666     | +1.5%    |

Decode wins land at 1KB+ where the repeated-field pattern dominates
(Person has 26 emails). At 10B no repeats fire, so the small -3.2% is
noise. Encode unchanged path, flat. Profile's "6% of decode time"
target translated cleanly into +5–7% on sizes that exercise repeated
fields.

**Runtime mode:** flat. cch only touches mode=full repeated emit;
runtime dispatches through `pb.codec` which already uses a different
append shape.

**Commit:** see git history for SHA.

---

## 2026-05-18 — 4kj: inline 1-byte tag fast path at decode call sites

**Task:** [tarantool-protobuf-4kj] Decoder: generated tag/length fast path

M cmd/protoc-gen-tarantool/internal/gen/inline.go => cmd/protoc-gen-tarantool/internal/gen/inline.go +19 -7
@@ 370,6 370,17 @@ func emitInlineDecode(w *writer, name string, m *protogen.Message, file *protoge
	w.line("    local result = {}")
	w.line("    local pos, len = 1, #buf")
	w.line("    local _uf")
	// Per-repeated-field counters. Replace `#list + 1` (re-traverses
	// the list every append) with `_n_<fname> = _n_<fname> + 1`. The
	// counter survives across loop iterations, so out-of-order wire
	// entries for the same field continue counting from the existing
	// position without re-scanning. Map fields don't need a counter
	// (hash keys, not array indices).
	for _, f := range m.Fields {
		if f.Desc.IsList() && !f.Desc.IsMap() {
			w.line("    local _n_%s = 0", string(f.Desc.Name()))
		}
	}
	w.line("    while pos <= len do")
	w.line("        local _tag_start = pos")
	w.line("        local id, wt")


@@ 496,6 507,7 @@ func emitInlineDecodeFieldBody(w *writer, f *protogen.Field, file *protogen.File

func emitInlineDecodeRepeated(w *writer, f *protogen.Field, fname string, file *protogen.File, selfPath string, imports map[string]string, prefix string) {
	dst := luaFieldAccess("result", fname)
	cnt := "_n_" + string(f.Desc.Name())
	w.line("            local list = %s", dst)
	w.line("            if list == nil then list = {}; %s = list end", dst)



@@ 507,11 519,11 @@ func emitInlineDecodeRepeated(w *writer, f *protogen.Field, fname string, file *
			w.line("            local payload")
			w.line("            payload, pos = pb.codec.decode_group(%s, buf, pos, %d)",
				descRef, f.Desc.Number())
			w.line("            list[#list + 1] = payload")
			w.line("            %s = %s + 1; list[%s] = payload", cnt, cnt, cnt)
		} else {
			w.line("            local payload")
			w.line("            payload, pos = wire.decode_len(buf, pos)")
			w.line("            list[#list + 1] = %s(payload)", ref)
			w.line("            %s = %s + 1; list[%s] = %s(payload)", cnt, cnt, cnt, ref)
		}
	case f.Enum != nil:
		// Enums are packable (proto3 default). Accept both packed and per-element.


@@ 522,12 534,12 @@ func emitInlineDecodeRepeated(w *writer, f *protogen.Field, fname string, file *
		w.line("                while p2 <= lim do")
		w.line("                    local u")
		w.line("                    u, p2 = wire.decode_varint(payload, p2)")
		w.line("                    list[#list + 1] = wire.varint_to_int32(u)")
		w.line("                    %s = %s + 1; list[%s] = wire.varint_to_int32(u)", cnt, cnt, cnt)
		w.line("                end")
		w.line("            else")
		w.line("                local u")
		w.line("                u, pos = wire.decode_varint(buf, pos)")
		w.line("                list[#list + 1] = wire.varint_to_int32(u)")
		w.line("                %s = %s + 1; list[%s] = wire.varint_to_int32(u)", cnt, cnt, cnt)
		w.line("            end")
	default:
		st := scalarName(f.Desc.Kind())


@@ 540,17 552,17 @@ func emitInlineDecodeRepeated(w *writer, f *protogen.Field, fname string, file *
			w.line("                while p2 <= lim do")
			w.line("                    local val")
			w.line("                    val, p2 = wire.decode_%s(payload, p2)", st)
			w.line("                    list[#list + 1] = val")
			w.line("                    %s = %s + 1; list[%s] = val", cnt, cnt, cnt)
			w.line("                end")
			w.line("            else")
			w.line("                local val")
			w.line("                val, pos = wire.decode_%s(buf, pos)", st)
			w.line("                list[#list + 1] = val")
			w.line("                %s = %s + 1; list[%s] = val", cnt, cnt, cnt)
			w.line("            end")
		} else {
			w.line("            local val")
			w.line("            val, pos = wire.decode_%s(buf, pos)", st)
			w.line("            list[#list + 1] = val")
			w.line("            %s = %s + 1; list[%s] = val", cnt, cnt, cnt)
		}
	}
}

M examples/expected/full/conformance/conformance_pb.lua => examples/expected/full/conformance/conformance_pb.lua +2 -1
@@ 376,6 376,7 @@ function M.FailureSet_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_test = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 394,7 395,7 @@ function M.FailureSet_decode(buf)
            if list == nil then list = {}; result.test = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = M.TestStatus_decode(payload)
            _n_test = _n_test + 1; list[_n_test] = M.TestStatus_decode(payload)
        else
            local _ebid = M.FailureSet_descriptor.extensions_by_id
            local _ext = _ebid and _ebid[id] or nil

M examples/expected/full/hello/hello_pb.lua => examples/expected/full/hello/hello_pb.lua +7 -4
@@ 1195,6 1195,9 @@ function M.Person_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_emails = 0
    local _n_friends = 0
    local _n_lucky_numbers = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 1221,7 1224,7 @@ function M.Person_decode(buf)
            if list == nil then list = {}; result.emails = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_emails = _n_emails + 1; list[_n_emails] = val
        elseif id == 4 then
            local u
            u, pos = wire.decode_varint(buf, pos)


@@ 1240,7 1243,7 @@ function M.Person_decode(buf)
            if list == nil then list = {}; result.friends = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = M.Person_decode(payload)
            _n_friends = _n_friends + 1; list[_n_friends] = M.Person_decode(payload)
        elseif id == 7 then
            local list = result.lucky_numbers
            if list == nil then list = {}; result.lucky_numbers = list end


@@ 1251,12 1254,12 @@ function M.Person_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_lucky_numbers = _n_lucky_numbers + 1; list[_n_lucky_numbers] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_lucky_numbers = _n_lucky_numbers + 1; list[_n_lucky_numbers] = val
            end
        elseif id == 8 then
            local val

M examples/expected/full/proto2_basic/proto2_basic_pb.lua => examples/expected/full/proto2_basic/proto2_basic_pb.lua +16 -10
@@ 550,6 550,9 @@ function M.Cardinality_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_packed_default = 0
    local _n_explicitly_packed = 0
    local _n_explicitly_unpacked = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 581,12 584,12 @@ function M.Cardinality_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_default = _n_packed_default + 1; list[_n_packed_default] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_packed_default = _n_packed_default + 1; list[_n_packed_default] = val
            end
        elseif id == 4 then
            local list = result.explicitly_packed


@@ 598,12 601,12 @@ function M.Cardinality_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_explicitly_packed = _n_explicitly_packed + 1; list[_n_explicitly_packed] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_explicitly_packed = _n_explicitly_packed + 1; list[_n_explicitly_packed] = val
            end
        elseif id == 5 then
            local list = result.explicitly_unpacked


@@ 615,12 618,12 @@ function M.Cardinality_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_explicitly_unpacked = _n_explicitly_unpacked + 1; list[_n_explicitly_unpacked] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_explicitly_unpacked = _n_explicitly_unpacked + 1; list[_n_explicitly_unpacked] = val
            end
        else
            local _ebid = M.Cardinality_descriptor.extensions_by_id


@@ 924,6 927,7 @@ function M.WithGroup_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_repgroup = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 951,7 955,7 @@ function M.WithGroup_decode(buf)
            if list == nil then list = {}; result.repgroup = list end
            local payload
            payload, pos = pb.codec.decode_group(M.WithGroup_RepGroup_descriptor, buf, pos, 4)
            list[#list + 1] = payload
            _n_repgroup = _n_repgroup + 1; list[_n_repgroup] = payload
        else
            local _ebid = M.WithGroup_descriptor.extensions_by_id
            local _ext = _ebid and _ebid[id] or nil


@@ 1304,6 1308,8 @@ function M.BenchPayload_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_lucky_numbers = 0
    local _n_tags = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 1339,19 1345,19 @@ function M.BenchPayload_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_lucky_numbers = _n_lucky_numbers + 1; list[_n_lucky_numbers] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_lucky_numbers = _n_lucky_numbers + 1; list[_n_lucky_numbers] = val
            end
        elseif id == 5 then
            local list = result.tags
            if list == nil then list = {}; result.tags = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_tags = _n_tags + 1; list[_n_tags] = val
        elseif id == 6 then
            local payload
            payload, pos = wire.decode_len(buf, pos)

M examples/expected/full/protobuf_test_messages/proto2/test_messages_proto2_pb.lua => examples/expected/full/protobuf_test_messages/proto2/test_messages_proto2_pb.lua +146 -95
@@ 2612,6 2612,55 @@ function M.TestAllTypesProto2_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_repeated_int32 = 0
    local _n_repeated_int64 = 0
    local _n_repeated_uint32 = 0
    local _n_repeated_uint64 = 0
    local _n_repeated_sint32 = 0
    local _n_repeated_sint64 = 0
    local _n_repeated_fixed32 = 0
    local _n_repeated_fixed64 = 0
    local _n_repeated_sfixed32 = 0
    local _n_repeated_sfixed64 = 0
    local _n_repeated_float = 0
    local _n_repeated_double = 0
    local _n_repeated_bool = 0
    local _n_repeated_string = 0
    local _n_repeated_bytes = 0
    local _n_repeated_nested_message = 0
    local _n_repeated_foreign_message = 0
    local _n_repeated_nested_enum = 0
    local _n_repeated_foreign_enum = 0
    local _n_repeated_string_piece = 0
    local _n_repeated_cord = 0
    local _n_packed_int32 = 0
    local _n_packed_int64 = 0
    local _n_packed_uint32 = 0
    local _n_packed_uint64 = 0
    local _n_packed_sint32 = 0
    local _n_packed_sint64 = 0
    local _n_packed_fixed32 = 0
    local _n_packed_fixed64 = 0
    local _n_packed_sfixed32 = 0
    local _n_packed_sfixed64 = 0
    local _n_packed_float = 0
    local _n_packed_double = 0
    local _n_packed_bool = 0
    local _n_packed_nested_enum = 0
    local _n_unpacked_int32 = 0
    local _n_unpacked_int64 = 0
    local _n_unpacked_uint32 = 0
    local _n_unpacked_uint64 = 0
    local _n_unpacked_sint32 = 0
    local _n_unpacked_sint64 = 0
    local _n_unpacked_fixed32 = 0
    local _n_unpacked_fixed64 = 0
    local _n_unpacked_sfixed32 = 0
    local _n_unpacked_sfixed64 = 0
    local _n_unpacked_float = 0
    local _n_unpacked_double = 0
    local _n_unpacked_bool = 0
    local _n_unpacked_nested_enum = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 2738,12 2787,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_int32 = _n_repeated_int32 + 1; list[_n_repeated_int32] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_repeated_int32 = _n_repeated_int32 + 1; list[_n_repeated_int32] = val
            end
        elseif id == 32 then
            local list = result.repeated_int64


@@ 2755,12 2804,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_int64 = _n_repeated_int64 + 1; list[_n_repeated_int64] = val
                end
            else
                local val
                val, pos = wire.decode_int64(buf, pos)
                list[#list + 1] = val
                _n_repeated_int64 = _n_repeated_int64 + 1; list[_n_repeated_int64] = val
            end
        elseif id == 33 then
            local list = result.repeated_uint32


@@ 2772,12 2821,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_uint32 = _n_repeated_uint32 + 1; list[_n_repeated_uint32] = val
                end
            else
                local val
                val, pos = wire.decode_uint32(buf, pos)
                list[#list + 1] = val
                _n_repeated_uint32 = _n_repeated_uint32 + 1; list[_n_repeated_uint32] = val
            end
        elseif id == 34 then
            local list = result.repeated_uint64


@@ 2789,12 2838,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_uint64 = _n_repeated_uint64 + 1; list[_n_repeated_uint64] = val
                end
            else
                local val
                val, pos = wire.decode_uint64(buf, pos)
                list[#list + 1] = val
                _n_repeated_uint64 = _n_repeated_uint64 + 1; list[_n_repeated_uint64] = val
            end
        elseif id == 35 then
            local list = result.repeated_sint32


@@ 2806,12 2855,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sint32 = _n_repeated_sint32 + 1; list[_n_repeated_sint32] = val
                end
            else
                local val
                val, pos = wire.decode_sint32(buf, pos)
                list[#list + 1] = val
                _n_repeated_sint32 = _n_repeated_sint32 + 1; list[_n_repeated_sint32] = val
            end
        elseif id == 36 then
            local list = result.repeated_sint64


@@ 2823,12 2872,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sint64 = _n_repeated_sint64 + 1; list[_n_repeated_sint64] = val
                end
            else
                local val
                val, pos = wire.decode_sint64(buf, pos)
                list[#list + 1] = val
                _n_repeated_sint64 = _n_repeated_sint64 + 1; list[_n_repeated_sint64] = val
            end
        elseif id == 37 then
            local list = result.repeated_fixed32


@@ 2840,12 2889,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_fixed32 = _n_repeated_fixed32 + 1; list[_n_repeated_fixed32] = val
                end
            else
                local val
                val, pos = wire.decode_fixed32(buf, pos)
                list[#list + 1] = val
                _n_repeated_fixed32 = _n_repeated_fixed32 + 1; list[_n_repeated_fixed32] = val
            end
        elseif id == 38 then
            local list = result.repeated_fixed64


@@ 2857,12 2906,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_fixed64 = _n_repeated_fixed64 + 1; list[_n_repeated_fixed64] = val
                end
            else
                local val
                val, pos = wire.decode_fixed64(buf, pos)
                list[#list + 1] = val
                _n_repeated_fixed64 = _n_repeated_fixed64 + 1; list[_n_repeated_fixed64] = val
            end
        elseif id == 39 then
            local list = result.repeated_sfixed32


@@ 2874,12 2923,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sfixed32 = _n_repeated_sfixed32 + 1; list[_n_repeated_sfixed32] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed32(buf, pos)
                list[#list + 1] = val
                _n_repeated_sfixed32 = _n_repeated_sfixed32 + 1; list[_n_repeated_sfixed32] = val
            end
        elseif id == 40 then
            local list = result.repeated_sfixed64


@@ 2891,12 2940,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sfixed64 = _n_repeated_sfixed64 + 1; list[_n_repeated_sfixed64] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed64(buf, pos)
                list[#list + 1] = val
                _n_repeated_sfixed64 = _n_repeated_sfixed64 + 1; list[_n_repeated_sfixed64] = val
            end
        elseif id == 41 then
            local list = result.repeated_float


@@ 2908,12 2957,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_float(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_float = _n_repeated_float + 1; list[_n_repeated_float] = val
                end
            else
                local val
                val, pos = wire.decode_float(buf, pos)
                list[#list + 1] = val
                _n_repeated_float = _n_repeated_float + 1; list[_n_repeated_float] = val
            end
        elseif id == 42 then
            local list = result.repeated_double


@@ 2925,12 2974,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_double(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_double = _n_repeated_double + 1; list[_n_repeated_double] = val
                end
            else
                local val
                val, pos = wire.decode_double(buf, pos)
                list[#list + 1] = val
                _n_repeated_double = _n_repeated_double + 1; list[_n_repeated_double] = val
            end
        elseif id == 43 then
            local list = result.repeated_bool


@@ 2942,37 2991,37 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_bool(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_bool = _n_repeated_bool + 1; list[_n_repeated_bool] = val
                end
            else
                local val
                val, pos = wire.decode_bool(buf, pos)
                list[#list + 1] = val
                _n_repeated_bool = _n_repeated_bool + 1; list[_n_repeated_bool] = val
            end
        elseif id == 44 then
            local list = result.repeated_string
            if list == nil then list = {}; result.repeated_string = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = val
        elseif id == 45 then
            local list = result.repeated_bytes
            if list == nil then list = {}; result.repeated_bytes = list end
            local val
            val, pos = wire.decode_bytes(buf, pos)
            list[#list + 1] = val
            _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = val
        elseif id == 48 then
            local list = result.repeated_nested_message
            if list == nil then list = {}; result.repeated_nested_message = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = M.TestAllTypesProto2_NestedMessage_decode(payload)
            _n_repeated_nested_message = _n_repeated_nested_message + 1; list[_n_repeated_nested_message] = M.TestAllTypesProto2_NestedMessage_decode(payload)
        elseif id == 49 then
            local list = result.repeated_foreign_message
            if list == nil then list = {}; result.repeated_foreign_message = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = M.ForeignMessageProto2_decode(payload)
            _n_repeated_foreign_message = _n_repeated_foreign_message + 1; list[_n_repeated_foreign_message] = M.ForeignMessageProto2_decode(payload)
        elseif id == 51 then
            local list = result.repeated_nested_enum
            if list == nil then list = {}; result.repeated_nested_enum = list end


@@ 2983,12 3032,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_repeated_nested_enum = _n_repeated_nested_enum + 1; list[_n_repeated_nested_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_repeated_nested_enum = _n_repeated_nested_enum + 1; list[_n_repeated_nested_enum] = wire.varint_to_int32(u)
            end
        elseif id == 52 then
            local list = result.repeated_foreign_enum


@@ 3000,25 3049,25 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_repeated_foreign_enum = _n_repeated_foreign_enum + 1; list[_n_repeated_foreign_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_repeated_foreign_enum = _n_repeated_foreign_enum + 1; list[_n_repeated_foreign_enum] = wire.varint_to_int32(u)
            end
        elseif id == 54 then
            local list = result.repeated_string_piece
            if list == nil then list = {}; result.repeated_string_piece = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = val
        elseif id == 55 then
            local list = result.repeated_cord
            if list == nil then list = {}; result.repeated_cord = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = val
        elseif id == 75 then
            local list = result.packed_int32
            if list == nil then list = {}; result.packed_int32 = list end


@@ 3029,12 3078,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_int32 = _n_packed_int32 + 1; list[_n_packed_int32] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_packed_int32 = _n_packed_int32 + 1; list[_n_packed_int32] = val
            end
        elseif id == 76 then
            local list = result.packed_int64


@@ 3046,12 3095,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_int64 = _n_packed_int64 + 1; list[_n_packed_int64] = val
                end
            else
                local val
                val, pos = wire.decode_int64(buf, pos)
                list[#list + 1] = val
                _n_packed_int64 = _n_packed_int64 + 1; list[_n_packed_int64] = val
            end
        elseif id == 77 then
            local list = result.packed_uint32


@@ 3063,12 3112,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_uint32 = _n_packed_uint32 + 1; list[_n_packed_uint32] = val
                end
            else
                local val
                val, pos = wire.decode_uint32(buf, pos)
                list[#list + 1] = val
                _n_packed_uint32 = _n_packed_uint32 + 1; list[_n_packed_uint32] = val
            end
        elseif id == 78 then
            local list = result.packed_uint64


@@ 3080,12 3129,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_uint64 = _n_packed_uint64 + 1; list[_n_packed_uint64] = val
                end
            else
                local val
                val, pos = wire.decode_uint64(buf, pos)
                list[#list + 1] = val
                _n_packed_uint64 = _n_packed_uint64 + 1; list[_n_packed_uint64] = val
            end
        elseif id == 79 then
            local list = result.packed_sint32


@@ 3097,12 3146,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sint32 = _n_packed_sint32 + 1; list[_n_packed_sint32] = val
                end
            else
                local val
                val, pos = wire.decode_sint32(buf, pos)
                list[#list + 1] = val
                _n_packed_sint32 = _n_packed_sint32 + 1; list[_n_packed_sint32] = val
            end
        elseif id == 80 then
            local list = result.packed_sint64


@@ 3114,12 3163,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sint64 = _n_packed_sint64 + 1; list[_n_packed_sint64] = val
                end
            else
                local val
                val, pos = wire.decode_sint64(buf, pos)
                list[#list + 1] = val
                _n_packed_sint64 = _n_packed_sint64 + 1; list[_n_packed_sint64] = val
            end
        elseif id == 81 then
            local list = result.packed_fixed32


@@ 3131,12 3180,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_fixed32 = _n_packed_fixed32 + 1; list[_n_packed_fixed32] = val
                end
            else
                local val
                val, pos = wire.decode_fixed32(buf, pos)
                list[#list + 1] = val
                _n_packed_fixed32 = _n_packed_fixed32 + 1; list[_n_packed_fixed32] = val
            end
        elseif id == 82 then
            local list = result.packed_fixed64


@@ 3148,12 3197,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_fixed64 = _n_packed_fixed64 + 1; list[_n_packed_fixed64] = val
                end
            else
                local val
                val, pos = wire.decode_fixed64(buf, pos)
                list[#list + 1] = val
                _n_packed_fixed64 = _n_packed_fixed64 + 1; list[_n_packed_fixed64] = val
            end
        elseif id == 83 then
            local list = result.packed_sfixed32


@@ 3165,12 3214,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sfixed32 = _n_packed_sfixed32 + 1; list[_n_packed_sfixed32] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed32(buf, pos)
                list[#list + 1] = val
                _n_packed_sfixed32 = _n_packed_sfixed32 + 1; list[_n_packed_sfixed32] = val
            end
        elseif id == 84 then
            local list = result.packed_sfixed64


@@ 3182,12 3231,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sfixed64 = _n_packed_sfixed64 + 1; list[_n_packed_sfixed64] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed64(buf, pos)
                list[#list + 1] = val
                _n_packed_sfixed64 = _n_packed_sfixed64 + 1; list[_n_packed_sfixed64] = val
            end
        elseif id == 85 then
            local list = result.packed_float


@@ 3199,12 3248,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_float(payload, p2)
                    list[#list + 1] = val
                    _n_packed_float = _n_packed_float + 1; list[_n_packed_float] = val
                end
            else
                local val
                val, pos = wire.decode_float(buf, pos)
                list[#list + 1] = val
                _n_packed_float = _n_packed_float + 1; list[_n_packed_float] = val
            end
        elseif id == 86 then
            local list = result.packed_double


@@ 3216,12 3265,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_double(payload, p2)
                    list[#list + 1] = val
                    _n_packed_double = _n_packed_double + 1; list[_n_packed_double] = val
                end
            else
                local val
                val, pos = wire.decode_double(buf, pos)
                list[#list + 1] = val
                _n_packed_double = _n_packed_double + 1; list[_n_packed_double] = val
            end
        elseif id == 87 then
            local list = result.packed_bool


@@ 3233,12 3282,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_bool(payload, p2)
                    list[#list + 1] = val
                    _n_packed_bool = _n_packed_bool + 1; list[_n_packed_bool] = val
                end
            else
                local val
                val, pos = wire.decode_bool(buf, pos)
                list[#list + 1] = val
                _n_packed_bool = _n_packed_bool + 1; list[_n_packed_bool] = val
            end
        elseif id == 88 then
            local list = result.packed_nested_enum


@@ 3250,12 3299,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_packed_nested_enum = _n_packed_nested_enum + 1; list[_n_packed_nested_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_packed_nested_enum = _n_packed_nested_enum + 1; list[_n_packed_nested_enum] = wire.varint_to_int32(u)
            end
        elseif id == 89 then
            local list = result.unpacked_int32


@@ 3267,12 3316,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_int32 = _n_unpacked_int32 + 1; list[_n_unpacked_int32] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_int32 = _n_unpacked_int32 + 1; list[_n_unpacked_int32] = val
            end
        elseif id == 90 then
            local list = result.unpacked_int64


@@ 3284,12 3333,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_int64 = _n_unpacked_int64 + 1; list[_n_unpacked_int64] = val
                end
            else
                local val
                val, pos = wire.decode_int64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_int64 = _n_unpacked_int64 + 1; list[_n_unpacked_int64] = val
            end
        elseif id == 91 then
            local list = result.unpacked_uint32


@@ 3301,12 3350,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_uint32 = _n_unpacked_uint32 + 1; list[_n_unpacked_uint32] = val
                end
            else
                local val
                val, pos = wire.decode_uint32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_uint32 = _n_unpacked_uint32 + 1; list[_n_unpacked_uint32] = val
            end
        elseif id == 92 then
            local list = result.unpacked_uint64


@@ 3318,12 3367,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_uint64 = _n_unpacked_uint64 + 1; list[_n_unpacked_uint64] = val
                end
            else
                local val
                val, pos = wire.decode_uint64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_uint64 = _n_unpacked_uint64 + 1; list[_n_unpacked_uint64] = val
            end
        elseif id == 93 then
            local list = result.unpacked_sint32


@@ 3335,12 3384,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sint32 = _n_unpacked_sint32 + 1; list[_n_unpacked_sint32] = val
                end
            else
                local val
                val, pos = wire.decode_sint32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sint32 = _n_unpacked_sint32 + 1; list[_n_unpacked_sint32] = val
            end
        elseif id == 94 then
            local list = result.unpacked_sint64


@@ 3352,12 3401,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sint64 = _n_unpacked_sint64 + 1; list[_n_unpacked_sint64] = val
                end
            else
                local val
                val, pos = wire.decode_sint64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sint64 = _n_unpacked_sint64 + 1; list[_n_unpacked_sint64] = val
            end
        elseif id == 95 then
            local list = result.unpacked_fixed32


@@ 3369,12 3418,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_fixed32 = _n_unpacked_fixed32 + 1; list[_n_unpacked_fixed32] = val
                end
            else
                local val
                val, pos = wire.decode_fixed32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_fixed32 = _n_unpacked_fixed32 + 1; list[_n_unpacked_fixed32] = val
            end
        elseif id == 96 then
            local list = result.unpacked_fixed64


@@ 3386,12 3435,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_fixed64 = _n_unpacked_fixed64 + 1; list[_n_unpacked_fixed64] = val
                end
            else
                local val
                val, pos = wire.decode_fixed64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_fixed64 = _n_unpacked_fixed64 + 1; list[_n_unpacked_fixed64] = val
            end
        elseif id == 97 then
            local list = result.unpacked_sfixed32


@@ 3403,12 3452,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sfixed32 = _n_unpacked_sfixed32 + 1; list[_n_unpacked_sfixed32] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sfixed32 = _n_unpacked_sfixed32 + 1; list[_n_unpacked_sfixed32] = val
            end
        elseif id == 98 then
            local list = result.unpacked_sfixed64


@@ 3420,12 3469,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sfixed64 = _n_unpacked_sfixed64 + 1; list[_n_unpacked_sfixed64] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sfixed64 = _n_unpacked_sfixed64 + 1; list[_n_unpacked_sfixed64] = val
            end
        elseif id == 99 then
            local list = result.unpacked_float


@@ 3437,12 3486,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_float(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_float = _n_unpacked_float + 1; list[_n_unpacked_float] = val
                end
            else
                local val
                val, pos = wire.decode_float(buf, pos)
                list[#list + 1] = val
                _n_unpacked_float = _n_unpacked_float + 1; list[_n_unpacked_float] = val
            end
        elseif id == 100 then
            local list = result.unpacked_double


@@ 3454,12 3503,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_double(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_double = _n_unpacked_double + 1; list[_n_unpacked_double] = val
                end
            else
                local val
                val, pos = wire.decode_double(buf, pos)
                list[#list + 1] = val
                _n_unpacked_double = _n_unpacked_double + 1; list[_n_unpacked_double] = val
            end
        elseif id == 101 then
            local list = result.unpacked_bool


@@ 3471,12 3520,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_bool(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_bool = _n_unpacked_bool + 1; list[_n_unpacked_bool] = val
                end
            else
                local val
                val, pos = wire.decode_bool(buf, pos)
                list[#list + 1] = val
                _n_unpacked_bool = _n_unpacked_bool + 1; list[_n_unpacked_bool] = val
            end
        elseif id == 102 then
            local list = result.unpacked_nested_enum


@@ 3488,12 3537,12 @@ function M.TestAllTypesProto2_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_unpacked_nested_enum = _n_unpacked_nested_enum + 1; list[_n_unpacked_nested_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_unpacked_nested_enum = _n_unpacked_nested_enum + 1; list[_n_unpacked_nested_enum] = wire.varint_to_int32(u)
            end
        elseif id == 56 then
            local map = result.map_int32_int32


@@ 5116,6 5165,7 @@ function M.UnknownToTestAllTypes_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_repeated_int32 = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 5169,12 5219,12 @@ function M.UnknownToTestAllTypes_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_int32 = _n_repeated_int32 + 1; list[_n_repeated_int32] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_repeated_int32 = _n_repeated_int32 + 1; list[_n_repeated_int32] = val
            end
        else
            local _ebid = M.UnknownToTestAllTypes_descriptor.extensions_by_id


@@ 5645,6 5695,7 @@ function M.ProtoWithKeywords_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_requires = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 5671,7 5722,7 @@ function M.ProtoWithKeywords_decode(buf)
            if list == nil then list = {}; result.requires = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_requires = _n_requires + 1; list[_n_requires] = val
        else
            local _ebid = M.ProtoWithKeywords_descriptor.extensions_by_id
            local _ext = _ebid and _ebid[id] or nil

M examples/expected/full/protobuf_test_messages/proto3/test_messages_proto3_pb.lua => examples/expected/full/protobuf_test_messages/proto3/test_messages_proto3_pb.lua +175 -109
@@ 2766,6 2766,72 @@ function M.TestAllTypesProto3_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_repeated_int32 = 0
    local _n_repeated_int64 = 0
    local _n_repeated_uint32 = 0
    local _n_repeated_uint64 = 0
    local _n_repeated_sint32 = 0
    local _n_repeated_sint64 = 0
    local _n_repeated_fixed32 = 0
    local _n_repeated_fixed64 = 0
    local _n_repeated_sfixed32 = 0
    local _n_repeated_sfixed64 = 0
    local _n_repeated_float = 0
    local _n_repeated_double = 0
    local _n_repeated_bool = 0
    local _n_repeated_string = 0
    local _n_repeated_bytes = 0
    local _n_repeated_nested_message = 0
    local _n_repeated_foreign_message = 0
    local _n_repeated_nested_enum = 0
    local _n_repeated_foreign_enum = 0
    local _n_repeated_string_piece = 0
    local _n_repeated_cord = 0
    local _n_packed_int32 = 0
    local _n_packed_int64 = 0
    local _n_packed_uint32 = 0
    local _n_packed_uint64 = 0
    local _n_packed_sint32 = 0
    local _n_packed_sint64 = 0
    local _n_packed_fixed32 = 0
    local _n_packed_fixed64 = 0
    local _n_packed_sfixed32 = 0
    local _n_packed_sfixed64 = 0
    local _n_packed_float = 0
    local _n_packed_double = 0
    local _n_packed_bool = 0
    local _n_packed_nested_enum = 0
    local _n_unpacked_int32 = 0
    local _n_unpacked_int64 = 0
    local _n_unpacked_uint32 = 0
    local _n_unpacked_uint64 = 0
    local _n_unpacked_sint32 = 0
    local _n_unpacked_sint64 = 0
    local _n_unpacked_fixed32 = 0
    local _n_unpacked_fixed64 = 0
    local _n_unpacked_sfixed32 = 0
    local _n_unpacked_sfixed64 = 0
    local _n_unpacked_float = 0
    local _n_unpacked_double = 0
    local _n_unpacked_bool = 0
    local _n_unpacked_nested_enum = 0
    local _n_repeated_bool_wrapper = 0
    local _n_repeated_int32_wrapper = 0
    local _n_repeated_int64_wrapper = 0
    local _n_repeated_uint32_wrapper = 0
    local _n_repeated_uint64_wrapper = 0
    local _n_repeated_float_wrapper = 0
    local _n_repeated_double_wrapper = 0
    local _n_repeated_string_wrapper = 0
    local _n_repeated_bytes_wrapper = 0
    local _n_repeated_duration = 0
    local _n_repeated_timestamp = 0
    local _n_repeated_fieldmask = 0
    local _n_repeated_struct = 0
    local _n_repeated_any = 0
    local _n_repeated_value = 0
    local _n_repeated_list_value = 0
    local _n_repeated_empty = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 2896,12 2962,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_int32 = _n_repeated_int32 + 1; list[_n_repeated_int32] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_repeated_int32 = _n_repeated_int32 + 1; list[_n_repeated_int32] = val
            end
        elseif id == 32 then
            local list = result.repeated_int64


@@ 2913,12 2979,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_int64 = _n_repeated_int64 + 1; list[_n_repeated_int64] = val
                end
            else
                local val
                val, pos = wire.decode_int64(buf, pos)
                list[#list + 1] = val
                _n_repeated_int64 = _n_repeated_int64 + 1; list[_n_repeated_int64] = val
            end
        elseif id == 33 then
            local list = result.repeated_uint32


@@ 2930,12 2996,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_uint32 = _n_repeated_uint32 + 1; list[_n_repeated_uint32] = val
                end
            else
                local val
                val, pos = wire.decode_uint32(buf, pos)
                list[#list + 1] = val
                _n_repeated_uint32 = _n_repeated_uint32 + 1; list[_n_repeated_uint32] = val
            end
        elseif id == 34 then
            local list = result.repeated_uint64


@@ 2947,12 3013,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_uint64 = _n_repeated_uint64 + 1; list[_n_repeated_uint64] = val
                end
            else
                local val
                val, pos = wire.decode_uint64(buf, pos)
                list[#list + 1] = val
                _n_repeated_uint64 = _n_repeated_uint64 + 1; list[_n_repeated_uint64] = val
            end
        elseif id == 35 then
            local list = result.repeated_sint32


@@ 2964,12 3030,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sint32 = _n_repeated_sint32 + 1; list[_n_repeated_sint32] = val
                end
            else
                local val
                val, pos = wire.decode_sint32(buf, pos)
                list[#list + 1] = val
                _n_repeated_sint32 = _n_repeated_sint32 + 1; list[_n_repeated_sint32] = val
            end
        elseif id == 36 then
            local list = result.repeated_sint64


@@ 2981,12 3047,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sint64 = _n_repeated_sint64 + 1; list[_n_repeated_sint64] = val
                end
            else
                local val
                val, pos = wire.decode_sint64(buf, pos)
                list[#list + 1] = val
                _n_repeated_sint64 = _n_repeated_sint64 + 1; list[_n_repeated_sint64] = val
            end
        elseif id == 37 then
            local list = result.repeated_fixed32


@@ 2998,12 3064,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_fixed32 = _n_repeated_fixed32 + 1; list[_n_repeated_fixed32] = val
                end
            else
                local val
                val, pos = wire.decode_fixed32(buf, pos)
                list[#list + 1] = val
                _n_repeated_fixed32 = _n_repeated_fixed32 + 1; list[_n_repeated_fixed32] = val
            end
        elseif id == 38 then
            local list = result.repeated_fixed64


@@ 3015,12 3081,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_fixed64 = _n_repeated_fixed64 + 1; list[_n_repeated_fixed64] = val
                end
            else
                local val
                val, pos = wire.decode_fixed64(buf, pos)
                list[#list + 1] = val
                _n_repeated_fixed64 = _n_repeated_fixed64 + 1; list[_n_repeated_fixed64] = val
            end
        elseif id == 39 then
            local list = result.repeated_sfixed32


@@ 3032,12 3098,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed32(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sfixed32 = _n_repeated_sfixed32 + 1; list[_n_repeated_sfixed32] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed32(buf, pos)
                list[#list + 1] = val
                _n_repeated_sfixed32 = _n_repeated_sfixed32 + 1; list[_n_repeated_sfixed32] = val
            end
        elseif id == 40 then
            local list = result.repeated_sfixed64


@@ 3049,12 3115,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed64(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_sfixed64 = _n_repeated_sfixed64 + 1; list[_n_repeated_sfixed64] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed64(buf, pos)
                list[#list + 1] = val
                _n_repeated_sfixed64 = _n_repeated_sfixed64 + 1; list[_n_repeated_sfixed64] = val
            end
        elseif id == 41 then
            local list = result.repeated_float


@@ 3066,12 3132,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_float(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_float = _n_repeated_float + 1; list[_n_repeated_float] = val
                end
            else
                local val
                val, pos = wire.decode_float(buf, pos)
                list[#list + 1] = val
                _n_repeated_float = _n_repeated_float + 1; list[_n_repeated_float] = val
            end
        elseif id == 42 then
            local list = result.repeated_double


@@ 3083,12 3149,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_double(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_double = _n_repeated_double + 1; list[_n_repeated_double] = val
                end
            else
                local val
                val, pos = wire.decode_double(buf, pos)
                list[#list + 1] = val
                _n_repeated_double = _n_repeated_double + 1; list[_n_repeated_double] = val
            end
        elseif id == 43 then
            local list = result.repeated_bool


@@ 3100,37 3166,37 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_bool(payload, p2)
                    list[#list + 1] = val
                    _n_repeated_bool = _n_repeated_bool + 1; list[_n_repeated_bool] = val
                end
            else
                local val
                val, pos = wire.decode_bool(buf, pos)
                list[#list + 1] = val
                _n_repeated_bool = _n_repeated_bool + 1; list[_n_repeated_bool] = val
            end
        elseif id == 44 then
            local list = result.repeated_string
            if list == nil then list = {}; result.repeated_string = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = val
        elseif id == 45 then
            local list = result.repeated_bytes
            if list == nil then list = {}; result.repeated_bytes = list end
            local val
            val, pos = wire.decode_bytes(buf, pos)
            list[#list + 1] = val
            _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = val
        elseif id == 48 then
            local list = result.repeated_nested_message
            if list == nil then list = {}; result.repeated_nested_message = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = M.TestAllTypesProto3_NestedMessage_decode(payload)
            _n_repeated_nested_message = _n_repeated_nested_message + 1; list[_n_repeated_nested_message] = M.TestAllTypesProto3_NestedMessage_decode(payload)
        elseif id == 49 then
            local list = result.repeated_foreign_message
            if list == nil then list = {}; result.repeated_foreign_message = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = M.ForeignMessage_decode(payload)
            _n_repeated_foreign_message = _n_repeated_foreign_message + 1; list[_n_repeated_foreign_message] = M.ForeignMessage_decode(payload)
        elseif id == 51 then
            local list = result.repeated_nested_enum
            if list == nil then list = {}; result.repeated_nested_enum = list end


@@ 3141,12 3207,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_repeated_nested_enum = _n_repeated_nested_enum + 1; list[_n_repeated_nested_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_repeated_nested_enum = _n_repeated_nested_enum + 1; list[_n_repeated_nested_enum] = wire.varint_to_int32(u)
            end
        elseif id == 52 then
            local list = result.repeated_foreign_enum


@@ 3158,25 3224,25 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_repeated_foreign_enum = _n_repeated_foreign_enum + 1; list[_n_repeated_foreign_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_repeated_foreign_enum = _n_repeated_foreign_enum + 1; list[_n_repeated_foreign_enum] = wire.varint_to_int32(u)
            end
        elseif id == 54 then
            local list = result.repeated_string_piece
            if list == nil then list = {}; result.repeated_string_piece = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = val
        elseif id == 55 then
            local list = result.repeated_cord
            if list == nil then list = {}; result.repeated_cord = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = val
        elseif id == 75 then
            local list = result.packed_int32
            if list == nil then list = {}; result.packed_int32 = list end


@@ 3187,12 3253,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_int32 = _n_packed_int32 + 1; list[_n_packed_int32] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_packed_int32 = _n_packed_int32 + 1; list[_n_packed_int32] = val
            end
        elseif id == 76 then
            local list = result.packed_int64


@@ 3204,12 3270,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_int64 = _n_packed_int64 + 1; list[_n_packed_int64] = val
                end
            else
                local val
                val, pos = wire.decode_int64(buf, pos)
                list[#list + 1] = val
                _n_packed_int64 = _n_packed_int64 + 1; list[_n_packed_int64] = val
            end
        elseif id == 77 then
            local list = result.packed_uint32


@@ 3221,12 3287,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_uint32 = _n_packed_uint32 + 1; list[_n_packed_uint32] = val
                end
            else
                local val
                val, pos = wire.decode_uint32(buf, pos)
                list[#list + 1] = val
                _n_packed_uint32 = _n_packed_uint32 + 1; list[_n_packed_uint32] = val
            end
        elseif id == 78 then
            local list = result.packed_uint64


@@ 3238,12 3304,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_uint64 = _n_packed_uint64 + 1; list[_n_packed_uint64] = val
                end
            else
                local val
                val, pos = wire.decode_uint64(buf, pos)
                list[#list + 1] = val
                _n_packed_uint64 = _n_packed_uint64 + 1; list[_n_packed_uint64] = val
            end
        elseif id == 79 then
            local list = result.packed_sint32


@@ 3255,12 3321,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sint32 = _n_packed_sint32 + 1; list[_n_packed_sint32] = val
                end
            else
                local val
                val, pos = wire.decode_sint32(buf, pos)
                list[#list + 1] = val
                _n_packed_sint32 = _n_packed_sint32 + 1; list[_n_packed_sint32] = val
            end
        elseif id == 80 then
            local list = result.packed_sint64


@@ 3272,12 3338,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sint64 = _n_packed_sint64 + 1; list[_n_packed_sint64] = val
                end
            else
                local val
                val, pos = wire.decode_sint64(buf, pos)
                list[#list + 1] = val
                _n_packed_sint64 = _n_packed_sint64 + 1; list[_n_packed_sint64] = val
            end
        elseif id == 81 then
            local list = result.packed_fixed32


@@ 3289,12 3355,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_fixed32 = _n_packed_fixed32 + 1; list[_n_packed_fixed32] = val
                end
            else
                local val
                val, pos = wire.decode_fixed32(buf, pos)
                list[#list + 1] = val
                _n_packed_fixed32 = _n_packed_fixed32 + 1; list[_n_packed_fixed32] = val
            end
        elseif id == 82 then
            local list = result.packed_fixed64


@@ 3306,12 3372,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_fixed64 = _n_packed_fixed64 + 1; list[_n_packed_fixed64] = val
                end
            else
                local val
                val, pos = wire.decode_fixed64(buf, pos)
                list[#list + 1] = val
                _n_packed_fixed64 = _n_packed_fixed64 + 1; list[_n_packed_fixed64] = val
            end
        elseif id == 83 then
            local list = result.packed_sfixed32


@@ 3323,12 3389,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed32(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sfixed32 = _n_packed_sfixed32 + 1; list[_n_packed_sfixed32] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed32(buf, pos)
                list[#list + 1] = val
                _n_packed_sfixed32 = _n_packed_sfixed32 + 1; list[_n_packed_sfixed32] = val
            end
        elseif id == 84 then
            local list = result.packed_sfixed64


@@ 3340,12 3406,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed64(payload, p2)
                    list[#list + 1] = val
                    _n_packed_sfixed64 = _n_packed_sfixed64 + 1; list[_n_packed_sfixed64] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed64(buf, pos)
                list[#list + 1] = val
                _n_packed_sfixed64 = _n_packed_sfixed64 + 1; list[_n_packed_sfixed64] = val
            end
        elseif id == 85 then
            local list = result.packed_float


@@ 3357,12 3423,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_float(payload, p2)
                    list[#list + 1] = val
                    _n_packed_float = _n_packed_float + 1; list[_n_packed_float] = val
                end
            else
                local val
                val, pos = wire.decode_float(buf, pos)
                list[#list + 1] = val
                _n_packed_float = _n_packed_float + 1; list[_n_packed_float] = val
            end
        elseif id == 86 then
            local list = result.packed_double


@@ 3374,12 3440,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_double(payload, p2)
                    list[#list + 1] = val
                    _n_packed_double = _n_packed_double + 1; list[_n_packed_double] = val
                end
            else
                local val
                val, pos = wire.decode_double(buf, pos)
                list[#list + 1] = val
                _n_packed_double = _n_packed_double + 1; list[_n_packed_double] = val
            end
        elseif id == 87 then
            local list = result.packed_bool


@@ 3391,12 3457,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_bool(payload, p2)
                    list[#list + 1] = val
                    _n_packed_bool = _n_packed_bool + 1; list[_n_packed_bool] = val
                end
            else
                local val
                val, pos = wire.decode_bool(buf, pos)
                list[#list + 1] = val
                _n_packed_bool = _n_packed_bool + 1; list[_n_packed_bool] = val
            end
        elseif id == 88 then
            local list = result.packed_nested_enum


@@ 3408,12 3474,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_packed_nested_enum = _n_packed_nested_enum + 1; list[_n_packed_nested_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_packed_nested_enum = _n_packed_nested_enum + 1; list[_n_packed_nested_enum] = wire.varint_to_int32(u)
            end
        elseif id == 89 then
            local list = result.unpacked_int32


@@ 3425,12 3491,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_int32 = _n_unpacked_int32 + 1; list[_n_unpacked_int32] = val
                end
            else
                local val
                val, pos = wire.decode_int32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_int32 = _n_unpacked_int32 + 1; list[_n_unpacked_int32] = val
            end
        elseif id == 90 then
            local list = result.unpacked_int64


@@ 3442,12 3508,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_int64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_int64 = _n_unpacked_int64 + 1; list[_n_unpacked_int64] = val
                end
            else
                local val
                val, pos = wire.decode_int64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_int64 = _n_unpacked_int64 + 1; list[_n_unpacked_int64] = val
            end
        elseif id == 91 then
            local list = result.unpacked_uint32


@@ 3459,12 3525,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_uint32 = _n_unpacked_uint32 + 1; list[_n_unpacked_uint32] = val
                end
            else
                local val
                val, pos = wire.decode_uint32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_uint32 = _n_unpacked_uint32 + 1; list[_n_unpacked_uint32] = val
            end
        elseif id == 92 then
            local list = result.unpacked_uint64


@@ 3476,12 3542,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_uint64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_uint64 = _n_unpacked_uint64 + 1; list[_n_unpacked_uint64] = val
                end
            else
                local val
                val, pos = wire.decode_uint64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_uint64 = _n_unpacked_uint64 + 1; list[_n_unpacked_uint64] = val
            end
        elseif id == 93 then
            local list = result.unpacked_sint32


@@ 3493,12 3559,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sint32 = _n_unpacked_sint32 + 1; list[_n_unpacked_sint32] = val
                end
            else
                local val
                val, pos = wire.decode_sint32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sint32 = _n_unpacked_sint32 + 1; list[_n_unpacked_sint32] = val
            end
        elseif id == 94 then
            local list = result.unpacked_sint64


@@ 3510,12 3576,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sint64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sint64 = _n_unpacked_sint64 + 1; list[_n_unpacked_sint64] = val
                end
            else
                local val
                val, pos = wire.decode_sint64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sint64 = _n_unpacked_sint64 + 1; list[_n_unpacked_sint64] = val
            end
        elseif id == 95 then
            local list = result.unpacked_fixed32


@@ 3527,12 3593,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_fixed32 = _n_unpacked_fixed32 + 1; list[_n_unpacked_fixed32] = val
                end
            else
                local val
                val, pos = wire.decode_fixed32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_fixed32 = _n_unpacked_fixed32 + 1; list[_n_unpacked_fixed32] = val
            end
        elseif id == 96 then
            local list = result.unpacked_fixed64


@@ 3544,12 3610,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_fixed64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_fixed64 = _n_unpacked_fixed64 + 1; list[_n_unpacked_fixed64] = val
                end
            else
                local val
                val, pos = wire.decode_fixed64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_fixed64 = _n_unpacked_fixed64 + 1; list[_n_unpacked_fixed64] = val
            end
        elseif id == 97 then
            local list = result.unpacked_sfixed32


@@ 3561,12 3627,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed32(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sfixed32 = _n_unpacked_sfixed32 + 1; list[_n_unpacked_sfixed32] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed32(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sfixed32 = _n_unpacked_sfixed32 + 1; list[_n_unpacked_sfixed32] = val
            end
        elseif id == 98 then
            local list = result.unpacked_sfixed64


@@ 3578,12 3644,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_sfixed64(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_sfixed64 = _n_unpacked_sfixed64 + 1; list[_n_unpacked_sfixed64] = val
                end
            else
                local val
                val, pos = wire.decode_sfixed64(buf, pos)
                list[#list + 1] = val
                _n_unpacked_sfixed64 = _n_unpacked_sfixed64 + 1; list[_n_unpacked_sfixed64] = val
            end
        elseif id == 99 then
            local list = result.unpacked_float


@@ 3595,12 3661,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_float(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_float = _n_unpacked_float + 1; list[_n_unpacked_float] = val
                end
            else
                local val
                val, pos = wire.decode_float(buf, pos)
                list[#list + 1] = val
                _n_unpacked_float = _n_unpacked_float + 1; list[_n_unpacked_float] = val
            end
        elseif id == 100 then
            local list = result.unpacked_double


@@ 3612,12 3678,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_double(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_double = _n_unpacked_double + 1; list[_n_unpacked_double] = val
                end
            else
                local val
                val, pos = wire.decode_double(buf, pos)
                list[#list + 1] = val
                _n_unpacked_double = _n_unpacked_double + 1; list[_n_unpacked_double] = val
            end
        elseif id == 101 then
            local list = result.unpacked_bool


@@ 3629,12 3695,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local val
                    val, p2 = wire.decode_bool(payload, p2)
                    list[#list + 1] = val
                    _n_unpacked_bool = _n_unpacked_bool + 1; list[_n_unpacked_bool] = val
                end
            else
                local val
                val, pos = wire.decode_bool(buf, pos)
                list[#list + 1] = val
                _n_unpacked_bool = _n_unpacked_bool + 1; list[_n_unpacked_bool] = val
            end
        elseif id == 102 then
            local list = result.unpacked_nested_enum


@@ 3646,12 3712,12 @@ function M.TestAllTypesProto3_decode(buf)
                while p2 <= lim do
                    local u
                    u, p2 = wire.decode_varint(payload, p2)
                    list[#list + 1] = wire.varint_to_int32(u)
                    _n_unpacked_nested_enum = _n_unpacked_nested_enum + 1; list[_n_unpacked_nested_enum] = wire.varint_to_int32(u)
                end
            else
                local u
                u, pos = wire.decode_varint(buf, pos)
                list[#list + 1] = wire.varint_to_int32(u)
                _n_unpacked_nested_enum = _n_unpacked_nested_enum + 1; list[_n_unpacked_nested_enum] = wire.varint_to_int32(u)
            end
        elseif id == 56 then
            local map = result.map_int32_int32


@@ 4213,55 4279,55 @@ function M.TestAllTypesProto3_decode(buf)
            if list == nil then list = {}; result.repeated_bool_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.BoolValue_decode(payload)
            _n_repeated_bool_wrapper = _n_repeated_bool_wrapper + 1; list[_n_repeated_bool_wrapper] = pb.wkt.BoolValue_decode(payload)
        elseif id == 212 then
            local list = result.repeated_int32_wrapper
            if list == nil then list = {}; result.repeated_int32_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Int32Value_decode(payload)
            _n_repeated_int32_wrapper = _n_repeated_int32_wrapper + 1; list[_n_repeated_int32_wrapper] = pb.wkt.Int32Value_decode(payload)
        elseif id == 213 then
            local list = result.repeated_int64_wrapper
            if list == nil then list = {}; result.repeated_int64_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Int64Value_decode(payload)
            _n_repeated_int64_wrapper = _n_repeated_int64_wrapper + 1; list[_n_repeated_int64_wrapper] = pb.wkt.Int64Value_decode(payload)
        elseif id == 214 then
            local list = result.repeated_uint32_wrapper
            if list == nil then list = {}; result.repeated_uint32_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.UInt32Value_decode(payload)
            _n_repeated_uint32_wrapper = _n_repeated_uint32_wrapper + 1; list[_n_repeated_uint32_wrapper] = pb.wkt.UInt32Value_decode(payload)
        elseif id == 215 then
            local list = result.repeated_uint64_wrapper
            if list == nil then list = {}; result.repeated_uint64_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.UInt64Value_decode(payload)
            _n_repeated_uint64_wrapper = _n_repeated_uint64_wrapper + 1; list[_n_repeated_uint64_wrapper] = pb.wkt.UInt64Value_decode(payload)
        elseif id == 216 then
            local list = result.repeated_float_wrapper
            if list == nil then list = {}; result.repeated_float_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.FloatValue_decode(payload)
            _n_repeated_float_wrapper = _n_repeated_float_wrapper + 1; list[_n_repeated_float_wrapper] = pb.wkt.FloatValue_decode(payload)
        elseif id == 217 then
            local list = result.repeated_double_wrapper
            if list == nil then list = {}; result.repeated_double_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.DoubleValue_decode(payload)
            _n_repeated_double_wrapper = _n_repeated_double_wrapper + 1; list[_n_repeated_double_wrapper] = pb.wkt.DoubleValue_decode(payload)
        elseif id == 218 then
            local list = result.repeated_string_wrapper
            if list == nil then list = {}; result.repeated_string_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.StringValue_decode(payload)
            _n_repeated_string_wrapper = _n_repeated_string_wrapper + 1; list[_n_repeated_string_wrapper] = pb.wkt.StringValue_decode(payload)
        elseif id == 219 then
            local list = result.repeated_bytes_wrapper
            if list == nil then list = {}; result.repeated_bytes_wrapper = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.BytesValue_decode(payload)
            _n_repeated_bytes_wrapper = _n_repeated_bytes_wrapper + 1; list[_n_repeated_bytes_wrapper] = pb.wkt.BytesValue_decode(payload)
        elseif id == 301 then
            local payload
            payload, pos = wire.decode_len(buf, pos)


@@ 4299,49 4365,49 @@ function M.TestAllTypesProto3_decode(buf)
            if list == nil then list = {}; result.repeated_duration = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Duration_decode(payload)
            _n_repeated_duration = _n_repeated_duration + 1; list[_n_repeated_duration] = pb.wkt.Duration_decode(payload)
        elseif id == 312 then
            local list = result.repeated_timestamp
            if list == nil then list = {}; result.repeated_timestamp = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Timestamp_decode(payload)
            _n_repeated_timestamp = _n_repeated_timestamp + 1; list[_n_repeated_timestamp] = pb.wkt.Timestamp_decode(payload)
        elseif id == 313 then
            local list = result.repeated_fieldmask
            if list == nil then list = {}; result.repeated_fieldmask = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.FieldMask_decode(payload)
            _n_repeated_fieldmask = _n_repeated_fieldmask + 1; list[_n_repeated_fieldmask] = pb.wkt.FieldMask_decode(payload)
        elseif id == 324 then
            local list = result.repeated_struct
            if list == nil then list = {}; result.repeated_struct = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Struct_decode(payload)
            _n_repeated_struct = _n_repeated_struct + 1; list[_n_repeated_struct] = pb.wkt.Struct_decode(payload)
        elseif id == 315 then
            local list = result.repeated_any
            if list == nil then list = {}; result.repeated_any = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Any_decode(payload)
            _n_repeated_any = _n_repeated_any + 1; list[_n_repeated_any] = pb.wkt.Any_decode(payload)
        elseif id == 316 then
            local list = result.repeated_value
            if list == nil then list = {}; result.repeated_value = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Value_decode(payload)
            _n_repeated_value = _n_repeated_value + 1; list[_n_repeated_value] = pb.wkt.Value_decode(payload)
        elseif id == 317 then
            local list = result.repeated_list_value
            if list == nil then list = {}; result.repeated_list_value = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.ListValue_decode(payload)
            _n_repeated_list_value = _n_repeated_list_value + 1; list[_n_repeated_list_value] = pb.wkt.ListValue_decode(payload)
        elseif id == 318 then
            local list = result.repeated_empty
            if list == nil then list = {}; result.repeated_empty = list end
            local payload
            payload, pos = wire.decode_len(buf, pos)
            list[#list + 1] = pb.wkt.Empty_decode(payload)
            _n_repeated_empty = _n_repeated_empty + 1; list[_n_repeated_empty] = pb.wkt.Empty_decode(payload)
        elseif id == 401 then
            local val
            val, pos = wire.decode_int32(buf, pos)

M examples/expected/full/quickstart/quickstart_pb.lua => examples/expected/full/quickstart/quickstart_pb.lua +2 -1
@@ 137,6 137,7 @@ function M.User_decode(buf)
    local result = {}
    local pos, len = 1, #buf
    local _uf
    local _n_emails = 0
    while pos <= len do
        local _tag_start = pos
        local id, wt


@@ 167,7 168,7 @@ function M.User_decode(buf)
            if list == nil then list = {}; result.emails = list end
            local val
            val, pos = wire.decode_string(buf, pos)
            list[#list + 1] = val
            _n_emails = _n_emails + 1; list[_n_emails] = val
        else
            local _ebid = M.User_descriptor.extensions_by_id
            local _ext = _ebid and _ebid[id] or nil