diff --git a/packages/protobuf-bench/README.md b/packages/protobuf-bench/README.md index fdc782599..ed2acd763 100644 --- a/packages/protobuf-bench/README.md +++ b/packages/protobuf-bench/README.md @@ -10,5 +10,5 @@ server would usually do. | code generator | bundle size | minified | compressed | |---------------------|------------------------:|-----------------------:|-------------------:| -| protobuf-es | 97,510 b | 41,660 b | 10,845 b | +| protobuf-es | 97,734 b | 41,763 b | 10,857 b | | protobuf-javascript | 394,384 b | 288,654 b | 45,122 b | diff --git a/packages/protobuf-test/src/clone.test.ts b/packages/protobuf-test/src/clone.test.ts index 90b3aa1af..72860935a 100644 --- a/packages/protobuf-test/src/clone.test.ts +++ b/packages/protobuf-test/src/clone.test.ts @@ -15,6 +15,8 @@ import { describe, expect } from "@jest/globals"; import { MessageFieldMessage as TS_MessageFieldMessage } from "./gen/ts/extra/msg-message_pb.js"; import { MessageFieldMessage as JS_MessageFieldMessage } from "./gen/js/extra/msg-message_pb.js"; +import { Empty as TS_Empty } from "./gen/ts/google/protobuf/empty_pb.js"; +import { Empty as JS_Empty } from "./gen/js/google/protobuf/empty_pb.js"; import { RepeatedScalarValuesMessage as TS_RepeatedScalarValuesMessage, ScalarValuesMessage as TS_ScalarValuesMessage, @@ -26,7 +28,7 @@ import { import { WrappersMessage as TS_WrappersMessage } from "./gen/ts/extra/wkt-wrappers_pb.js"; import { WrappersMessage as JS_WrappersMessage } from "./gen/js/extra/wkt-wrappers_pb.js"; import { testMT } from "./helpers.js"; -import { BoolValue, protoInt64 } from "@bufbuild/protobuf"; +import { BoolValue, WireType, protoInt64 } from "@bufbuild/protobuf"; /* eslint-disable @typescript-eslint/ban-ts-comment */ @@ -146,4 +148,23 @@ describe("clone", function () { a.doubleValueField = 0.1; expect(b.doubleValueField).not.toBe(a.doubleValueField); }); + // We are using Empty wkt to test unknown fields. + testMT({ ts: TS_Empty, js: JS_Empty }, (messageType) => { + const a = new messageType(); + const bin = messageType.runtime.bin; + const unknownFields = [ + { no: 1, wireType: WireType.Bit32, data: new Uint8Array([1, 2, 3, 4]) }, + ]; + for (const unknowField of unknownFields) { + bin.onUnknownField( + a, + unknowField.no, + unknowField.wireType, + unknowField.data, + ); + } + const b = a.clone(); + expect(b).toStrictEqual(a); + expect(bin.listUnknownFields(b)).toStrictEqual(unknownFields); + }); }); diff --git a/packages/protobuf/src/message.ts b/packages/protobuf/src/message.ts index 39552d547..cc9d3a1f1 100644 --- a/packages/protobuf/src/message.ts +++ b/packages/protobuf/src/message.ts @@ -40,6 +40,7 @@ export interface AnyMessage extends Message { export class Message = AnyMessage> { /** * Compare with a message of the same type. + * Note that this function disregards extensions and unknown fields. */ equals(other: T | PlainMessage | undefined | null): boolean { return this.getType().runtime.util.equals( diff --git a/packages/protobuf/src/private/util-common.ts b/packages/protobuf/src/private/util-common.ts index c2e1a5400..42f4e6340 100644 --- a/packages/protobuf/src/private/util-common.ts +++ b/packages/protobuf/src/private/util-common.ts @@ -230,6 +230,9 @@ export function makeUtilCommon(): Omit { } any[member.localName] = copy; } + for (const uf of type.runtime.bin.listUnknownFields(message)) { + type.runtime.bin.onUnknownField(any, uf.no, uf.wireType, uf.data); + } return target; }, };