2023-04-06 01:05:04 +00:00
|
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
import { Reader } from 'protobufjs';
|
|
|
|
|
|
|
|
type MessageWithUnknownFields = {
|
2023-07-12 17:54:37 +00:00
|
|
|
$unknownFields?: ReadonlyArray<Uint8Array>;
|
2023-04-06 01:05:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an array of the tags of unknown fields in a protobuf message.
|
|
|
|
*
|
|
|
|
* Clients may use slightly different definitions of our protos, in cases where
|
2023-07-12 17:54:37 +00:00
|
|
|
* we don't recognize a field, we store it in `$unknownFields`.
|
2023-04-06 01:05:04 +00:00
|
|
|
*
|
|
|
|
* For example:
|
|
|
|
*
|
|
|
|
* ```proto
|
|
|
|
* // Our proto definition
|
|
|
|
* message Foo {
|
|
|
|
* optional string bar = 1;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* // Their proto definition
|
|
|
|
* message Foo {
|
|
|
|
* optional string bar = 1;
|
|
|
|
* optional string baz = 2;
|
|
|
|
* }
|
|
|
|
* ```
|
|
|
|
*
|
2023-07-12 17:54:37 +00:00
|
|
|
* If we receive a message with `baz` set, we'll store it in `$unknownFields`.
|
2023-04-06 01:05:04 +00:00
|
|
|
*
|
|
|
|
* This function will then return `[2]`.
|
|
|
|
*/
|
|
|
|
export function inspectUnknownFieldTags(
|
|
|
|
message: MessageWithUnknownFields
|
|
|
|
): Array<number> {
|
|
|
|
return (
|
2023-07-12 17:54:37 +00:00
|
|
|
message.$unknownFields?.map(field => {
|
2023-04-06 01:05:04 +00:00
|
|
|
// https://protobuf.dev/programming-guides/encoding/
|
|
|
|
// The first byte of a field is a varint encoding the tag bit-shifted << 3
|
|
|
|
// eslint-disable-next-line no-bitwise
|
|
|
|
return new Reader(field).uint32() >>> 3;
|
|
|
|
}) ?? []
|
|
|
|
);
|
|
|
|
}
|