blob: e34fdb4e8c36b8411d5fc760b97cc50f8e3d7399 [file] [edit]
// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "upb/wire/decode_fast/dispatch.h"
#include <stdint.h>
#include "upb/mini_table/message.h"
#include "upb/wire/decode_fast/data.h"
#include "upb/wire/internal/decoder.h"
#include "upb/wire/internal/eps_copy_input_stream.h"
// Must be last.
#include "upb/port/def.inc"
UPB_NOINLINE UPB_PRESERVE_NONE upb_FastDecoder_Return
upb_DecodeFast_MessageIsDoneFallback(UPB_PARSE_PARAMS) {
int overrun;
switch (UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneStatus)(&d->input, ptr,
&overrun)) {
case kUpb_IsDoneStatus_Done: {
// We've reach end-of-message. Sync hasbits and maybe check required
// fields.
d->message_is_done = true;
upb_DecodeFast_SetHasbits(msg, hasbits);
return (upb_FastDecoder_Return){
.ptr = UPB_UNLIKELY(table->UPB_PRIVATE(required_count))
? _upb_Decoder_CheckRequired(d, ptr, msg, table)
: ptr};
}
case kUpb_IsDoneStatus_NeedFallback:
// We've reached end-of-buffer. Refresh the buffer.
ptr = UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(EPS(d), ptr,
overrun);
// We successfully refreshed the buffer (otherwise the function above
// would have thrown an error with longjmp()). So continue with the
// fast decoder.
uint16_t tag = _upb_FastDecoder_LoadTag(ptr);
_upb_Decoder_Trace(d, 'r');
data2 = upb_DecodeFastData2_PackOriginalTag(data2, tag);
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS);
case kUpb_IsDoneStatus_NotDone: // Handled by caller.
default:
UPB_UNREACHABLE();
}
}
upb_FastDecoder_Return _upb_FastDecoder_ErrorJmp2(upb_Decoder* d) {
UPB_LONGJMP(d->err->buf, 1);
return (upb_FastDecoder_Return){.ptr = NULL};
}