@tt-a1i/openpi 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -10
- package/SETUP.md +8 -2
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/bin/openpi.js +25 -15
- package/extensions/ai-providers/LICENSE.upstream +23 -0
- package/extensions/ai-providers/README.md +59 -0
- package/extensions/ai-providers/antigravity/credentials.ts +52 -0
- package/extensions/ai-providers/antigravity/discovery.ts +130 -0
- package/extensions/ai-providers/antigravity/google-conversion.ts +455 -0
- package/extensions/ai-providers/antigravity/models.ts +84 -0
- package/extensions/ai-providers/antigravity/oauth.ts +700 -0
- package/extensions/ai-providers/antigravity/provider.ts +1116 -0
- package/extensions/ai-providers/antigravity/routing.ts +340 -0
- package/extensions/ai-providers/antigravity/with-resolvers.d.ts +19 -0
- package/extensions/ai-providers/cursor/constants.ts +5 -0
- package/extensions/ai-providers/cursor/credentials.ts +14 -0
- package/extensions/ai-providers/cursor/discovery.ts +291 -0
- package/extensions/ai-providers/cursor/input-images.ts +106 -0
- package/extensions/ai-providers/cursor/models.ts +45 -0
- package/extensions/ai-providers/cursor/oauth.ts +263 -0
- package/extensions/ai-providers/cursor/proto.ts +1064 -0
- package/extensions/ai-providers/cursor/protobuf.ts +1171 -0
- package/extensions/ai-providers/cursor/provider.ts +1175 -0
- package/extensions/ai-providers/cursor/proxy.ts +213 -0
- package/extensions/ai-providers/cursor/with-resolvers.d.ts +12 -0
- package/extensions/ai-providers/index.ts +86 -0
- package/extensions/ai-providers/oauth-adapter.ts +81 -0
- package/extensions/ai-providers/usage.ts +10 -0
- package/extensions/background-terminals/index.ts +8 -1
- package/extensions/background-terminals/src/manager.ts +3 -5
- package/extensions/background-terminals/src/result-delivery.ts +43 -23
- package/extensions/cron/index.ts +68 -27
- package/extensions/cron/schedule.ts +5 -1
- package/extensions/model-info/cache-diagnostics.ts +220 -0
- package/extensions/model-info/index.ts +45 -1
- package/extensions/plan-mode/index.ts +75 -4
- package/extensions/setup/index.ts +15 -3
- package/extensions/shared/child-session.ts +25 -5
- package/extensions/shared/completion-inbox.ts +193 -0
- package/extensions/shared/setup-config.ts +10 -1
- package/extensions/shared/structured-output.ts +154 -0
- package/extensions/subagents/index.ts +44 -4
- package/extensions/subagents/src/backends/pi.ts +76 -5
- package/extensions/subagents/src/domain.ts +16 -1
- package/extensions/subagents/src/manager.ts +5 -0
- package/extensions/subagents/src/prompt.ts +17 -3
- package/extensions/subagents/src/result-artifact.ts +32 -0
- package/extensions/subagents/src/result-delivery.ts +33 -14
- package/extensions/ui-customization/footer.ts +16 -5
- package/extensions/user-input-fold/index.ts +42 -6
- package/extensions/web/index.ts +25 -2
- package/extensions/workflows/acceptance.ts +43 -19
- package/extensions/workflows/completion-projection.ts +3 -1
- package/extensions/workflows/dashboard.ts +8 -0
- package/extensions/workflows/index.ts +13 -0
- package/extensions/workflows/model.ts +5 -1
- package/extensions/workflows/prompt.ts +4 -10
- package/extensions/workflows/result-delivery.ts +96 -22
- package/extensions/workflows/retention.ts +6 -0
- package/extensions/workflows/runner.ts +6 -71
- package/package.json +7 -7
- package/skills/subagents/REFERENCE.md +3 -2
- package/skills/subagents/SKILL.md +1 -0
- package/skills/workflows/REFERENCE.md +3 -3
- package/skills/workflows/SKILL.md +1 -1
- package/web/adapter/pi-adapter.ts +3 -0
- package/web/host/pi-coding-agent-entry.ts +162 -0
- package/web/host/web-host.ts +330 -50
- package/web/protocol/types.ts +5 -0
- package/web/runtime/pi-runtime.ts +240 -25
- package/web/runtime/types.ts +32 -1
- package/web/ui/app.js +343 -41
- package/web/ui/index.html +3 -0
- package/web/ui/styles.css +119 -37
|
@@ -0,0 +1,1171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from oh-my-pi@eab72e88e4,
|
|
3
|
+
* packages/catalog/src/discovery/protobuf.ts (MIT). Kept local so this
|
|
4
|
+
* extension has no @oh-my-pi package or subprocess dependency.
|
|
5
|
+
*/
|
|
6
|
+
import { Buffer } from "node:buffer";
|
|
7
|
+
|
|
8
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
9
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* High-performance, zero-builder protobuf wire codecs for @oh-my-pi/pi-catalog.
|
|
14
|
+
*
|
|
15
|
+
* Schemas are declared as static IR descriptors with near-zero module load overhead
|
|
16
|
+
* and lazy compilation on first encode/decode/create invocation.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** JSON values carried by `google.protobuf.Value` fields. */
|
|
20
|
+
export type JsonValue =
|
|
21
|
+
| null
|
|
22
|
+
| boolean
|
|
23
|
+
| number
|
|
24
|
+
| string
|
|
25
|
+
| JsonValue[]
|
|
26
|
+
| { [key: string]: JsonValue };
|
|
27
|
+
|
|
28
|
+
const textEncoder = new TextEncoder();
|
|
29
|
+
const textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
30
|
+
|
|
31
|
+
/** An unrecognised wire field retained for forward-compatible round-trips. */
|
|
32
|
+
export interface ProtoUnknownField {
|
|
33
|
+
no: number;
|
|
34
|
+
wireType: number;
|
|
35
|
+
data: Uint8Array;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Shared internal metadata present on every decoded protocol message. */
|
|
39
|
+
export interface ProtoMessage {
|
|
40
|
+
$typeName?: string;
|
|
41
|
+
$unknown?: ProtoUnknownField[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** A bidirectional codec for one protobuf message type. */
|
|
45
|
+
export interface MessageCodec<T extends ProtoMessage = ProtoMessage> {
|
|
46
|
+
(value: T): Uint8Array;
|
|
47
|
+
(value: Uint8Array): T;
|
|
48
|
+
/** Creates a message with protobuf defaults for omitted fields. */
|
|
49
|
+
create(value?: Partial<T>): T;
|
|
50
|
+
/** Encodes one message into protobuf wire bytes. */
|
|
51
|
+
encode(value: T): Uint8Array;
|
|
52
|
+
/** Decodes one protobuf message from wire bytes. */
|
|
53
|
+
decode(value: Uint8Array): T;
|
|
54
|
+
/** Converts a message to its protobuf JSON representation. */
|
|
55
|
+
toJson(value: T): JsonValue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Infers a message shape from a codec result. */
|
|
59
|
+
export type InferMessage<TCodec> =
|
|
60
|
+
TCodec extends MessageCodec<infer TMessage> ? TMessage : never;
|
|
61
|
+
|
|
62
|
+
/** Erases a referenced message's concrete shape for static field descriptors. */
|
|
63
|
+
export interface MessageReference {
|
|
64
|
+
encode(value: unknown): Uint8Array;
|
|
65
|
+
decode(value: Uint8Array): ProtoMessage;
|
|
66
|
+
toJson(value: unknown): JsonValue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type ScalarKind =
|
|
70
|
+
| "bool"
|
|
71
|
+
| "bytes"
|
|
72
|
+
| "double"
|
|
73
|
+
| "enum"
|
|
74
|
+
| "float"
|
|
75
|
+
| "int32"
|
|
76
|
+
| "int64"
|
|
77
|
+
| "string"
|
|
78
|
+
| "uint32"
|
|
79
|
+
| "uint64";
|
|
80
|
+
|
|
81
|
+
export type WireType = 0 | 1 | 2 | 5;
|
|
82
|
+
|
|
83
|
+
export interface ScalarFieldDesc {
|
|
84
|
+
readonly no: number;
|
|
85
|
+
readonly name: string;
|
|
86
|
+
readonly kind: ScalarKind;
|
|
87
|
+
readonly optional?: boolean;
|
|
88
|
+
readonly repeat?: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface MessageFieldDesc {
|
|
92
|
+
readonly no: number;
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly kind: "message";
|
|
95
|
+
readonly T: () => MessageReference;
|
|
96
|
+
readonly repeat?: boolean;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface EnumFieldDesc {
|
|
100
|
+
readonly no: number;
|
|
101
|
+
readonly name: string;
|
|
102
|
+
readonly kind: "enum";
|
|
103
|
+
readonly optional?: boolean;
|
|
104
|
+
readonly repeat?: boolean;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface MapFieldDesc {
|
|
108
|
+
readonly no: number;
|
|
109
|
+
readonly name: string;
|
|
110
|
+
readonly kind: "map";
|
|
111
|
+
readonly K: "string";
|
|
112
|
+
readonly V: ScalarKind | (() => MessageReference);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export type VariantDesc =
|
|
116
|
+
| { readonly no: number; readonly name: string; readonly kind: ScalarKind }
|
|
117
|
+
| {
|
|
118
|
+
readonly no: number;
|
|
119
|
+
readonly name: string;
|
|
120
|
+
readonly kind: "message";
|
|
121
|
+
readonly T: () => MessageReference;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export interface OneofFieldDesc {
|
|
125
|
+
readonly kind: "oneof";
|
|
126
|
+
readonly name: string;
|
|
127
|
+
readonly variants: readonly VariantDesc[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type FieldDesc =
|
|
131
|
+
| ScalarFieldDesc
|
|
132
|
+
| MessageFieldDesc
|
|
133
|
+
| EnumFieldDesc
|
|
134
|
+
| MapFieldDesc
|
|
135
|
+
| OneofFieldDesc;
|
|
136
|
+
|
|
137
|
+
/** Runtime representation shared by fields and variants. */
|
|
138
|
+
interface ValueCodec<TValue> {
|
|
139
|
+
readonly wireType: WireType;
|
|
140
|
+
readonly defaultValue: TValue | undefined;
|
|
141
|
+
encode(value: unknown, writer: Writer): void;
|
|
142
|
+
decode(reader: Reader): TValue;
|
|
143
|
+
toJson(value: unknown): JsonValue;
|
|
144
|
+
isDefault(value: unknown): boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
interface CompiledField {
|
|
148
|
+
readonly number: number;
|
|
149
|
+
encode(message: object, writer: Writer): void;
|
|
150
|
+
decode(
|
|
151
|
+
message: object,
|
|
152
|
+
reader: Reader,
|
|
153
|
+
wireType: WireType,
|
|
154
|
+
fieldNumber: number,
|
|
155
|
+
): void;
|
|
156
|
+
toJson(message: object, output: { [key: string]: JsonValue }): void;
|
|
157
|
+
initDefault(message: object): void;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Creates a high-performance, lazy protobuf message codec from an IR field descriptor list. */
|
|
161
|
+
export function pb<T extends ProtoMessage = ProtoMessage>(
|
|
162
|
+
typeName: string,
|
|
163
|
+
fields: readonly FieldDesc[] = [],
|
|
164
|
+
): MessageCodec<T> {
|
|
165
|
+
let compiled: MessageCodec<T> | undefined;
|
|
166
|
+
|
|
167
|
+
function getCodec(): MessageCodec<T> {
|
|
168
|
+
if (!compiled) compiled = compileCodec<T>(typeName, fields);
|
|
169
|
+
return compiled;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const codec = ((arg: T | Uint8Array) => {
|
|
173
|
+
if (arg instanceof Uint8Array) return getCodec().decode(arg);
|
|
174
|
+
return getCodec().encode(arg);
|
|
175
|
+
}) as MessageCodec<T>;
|
|
176
|
+
|
|
177
|
+
codec.create = (value?: Partial<T>): T => getCodec().create(value);
|
|
178
|
+
codec.encode = (value: T): Uint8Array => getCodec().encode(value);
|
|
179
|
+
codec.decode = (value: Uint8Array): T => getCodec().decode(value);
|
|
180
|
+
codec.toJson = (value: T): JsonValue => getCodec().toJson(value);
|
|
181
|
+
|
|
182
|
+
return codec;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Creates a message using its codec's protobuf defaults. */
|
|
186
|
+
export function create<TMessage extends ProtoMessage>(
|
|
187
|
+
codec: MessageCodec<TMessage>,
|
|
188
|
+
value?: Partial<TMessage>,
|
|
189
|
+
): TMessage {
|
|
190
|
+
return codec.create(value);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Encodes a message using its codec. */
|
|
194
|
+
export function toBinary<TMessage extends ProtoMessage>(
|
|
195
|
+
codec: MessageCodec<TMessage>,
|
|
196
|
+
value: TMessage,
|
|
197
|
+
): Uint8Array {
|
|
198
|
+
return codec.encode(value);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** Decodes wire bytes using a message codec. */
|
|
202
|
+
export function fromBinary<TMessage extends ProtoMessage>(
|
|
203
|
+
codec: MessageCodec<TMessage>,
|
|
204
|
+
value: Uint8Array,
|
|
205
|
+
): TMessage {
|
|
206
|
+
return codec.decode(value);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Converts a message to protobuf JSON using its codec. */
|
|
210
|
+
export function toJson<TMessage extends ProtoMessage>(
|
|
211
|
+
codec: MessageCodec<TMessage>,
|
|
212
|
+
value: TMessage,
|
|
213
|
+
): JsonValue {
|
|
214
|
+
return codec.toJson(value);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Encodes a JSON value as `google.protobuf.Value`. */
|
|
218
|
+
export function encodeJsonValue(value: JsonValue): Uint8Array {
|
|
219
|
+
const writer = new Writer();
|
|
220
|
+
writeJsonValue(writer, value);
|
|
221
|
+
return writer.finish();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** Decodes `google.protobuf.Value` wire bytes into a JSON value. */
|
|
225
|
+
export function decodeJsonValue(value: Uint8Array): JsonValue {
|
|
226
|
+
return readJsonValue(new Reader(value));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function compileCodec<T extends ProtoMessage>(
|
|
230
|
+
typeName: string,
|
|
231
|
+
fieldDescs: readonly FieldDesc[],
|
|
232
|
+
): MessageCodec<T> {
|
|
233
|
+
const compiledFields: CompiledField[] = [];
|
|
234
|
+
const byNumber = new Map<number, CompiledField>();
|
|
235
|
+
|
|
236
|
+
for (const desc of fieldDescs) {
|
|
237
|
+
if (desc.kind === "oneof") {
|
|
238
|
+
const oneofHandler = compileOneofField(desc);
|
|
239
|
+
compiledFields.push(oneofHandler);
|
|
240
|
+
for (const v of desc.variants) {
|
|
241
|
+
byNumber.set(v.no, oneofHandler);
|
|
242
|
+
}
|
|
243
|
+
} else if (desc.kind === "map") {
|
|
244
|
+
const mapHandler = compileMapField(desc);
|
|
245
|
+
compiledFields.push(mapHandler);
|
|
246
|
+
byNumber.set(desc.no, mapHandler);
|
|
247
|
+
} else if (desc.kind === "message") {
|
|
248
|
+
const msgHandler = desc.repeat
|
|
249
|
+
? compileRepeatedField(desc.name, desc.no, messageValue(desc.T))
|
|
250
|
+
: compileSingularField(desc.name, desc.no, messageValue(desc.T));
|
|
251
|
+
compiledFields.push(msgHandler);
|
|
252
|
+
byNumber.set(desc.no, msgHandler);
|
|
253
|
+
} else {
|
|
254
|
+
const valCodec = scalarValue(desc.kind);
|
|
255
|
+
const scalarHandler = desc.repeat
|
|
256
|
+
? compileRepeatedField(desc.name, desc.no, valCodec)
|
|
257
|
+
: compileSingularField(desc.name, desc.no, valCodec, desc.optional);
|
|
258
|
+
compiledFields.push(scalarHandler);
|
|
259
|
+
byNumber.set(desc.no, scalarHandler);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const codec: MessageCodec<T> = ((arg: T | Uint8Array) => {
|
|
264
|
+
if (arg instanceof Uint8Array) return codec.decode(arg);
|
|
265
|
+
return codec.encode(arg);
|
|
266
|
+
}) as MessageCodec<T>;
|
|
267
|
+
|
|
268
|
+
codec.create = (value?: Partial<T>): T => {
|
|
269
|
+
const message = (typeName ? { $typeName: typeName } : {}) as T;
|
|
270
|
+
for (const f of compiledFields) {
|
|
271
|
+
f.initDefault(message);
|
|
272
|
+
}
|
|
273
|
+
if (value) {
|
|
274
|
+
for (const key in value) {
|
|
275
|
+
const v = Reflect.get(value, key);
|
|
276
|
+
if (v !== undefined) {
|
|
277
|
+
Reflect.set(message, key, v);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return message;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
codec.encode = (value: T): Uint8Array => {
|
|
285
|
+
const writer = new Writer();
|
|
286
|
+
for (const f of compiledFields) {
|
|
287
|
+
f.encode(value, writer);
|
|
288
|
+
}
|
|
289
|
+
writeUnknownFields(value, writer);
|
|
290
|
+
return writer.finish();
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
codec.decode = (value: Uint8Array): T => {
|
|
294
|
+
const reader = new Reader(value);
|
|
295
|
+
const message = (typeName ? { $typeName: typeName } : {}) as T;
|
|
296
|
+
for (const f of compiledFields) {
|
|
297
|
+
f.initDefault(message);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
while (reader.pos < reader.len) {
|
|
301
|
+
const tag = reader.uint32();
|
|
302
|
+
const fieldNumber = tag >>> 3;
|
|
303
|
+
const wireType = tag & 7;
|
|
304
|
+
if (!isWireType(wireType)) {
|
|
305
|
+
throw new Error(
|
|
306
|
+
`Unsupported protobuf wire type ${wireType} at byte ${reader.pos}`,
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
const field = byNumber.get(fieldNumber);
|
|
310
|
+
if (field) {
|
|
311
|
+
field.decode(message, reader, wireType, fieldNumber);
|
|
312
|
+
} else {
|
|
313
|
+
const start = reader.pos;
|
|
314
|
+
reader.skip(wireType);
|
|
315
|
+
appendUnknownField(message, {
|
|
316
|
+
no: fieldNumber,
|
|
317
|
+
wireType,
|
|
318
|
+
data: reader.slice(start, reader.pos),
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return message;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
codec.toJson = (value: T): JsonValue => {
|
|
326
|
+
const output: { [key: string]: JsonValue } = {};
|
|
327
|
+
for (const f of compiledFields) {
|
|
328
|
+
f.toJson(value, output);
|
|
329
|
+
}
|
|
330
|
+
return output;
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
return codec;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function compileSingularField(
|
|
337
|
+
name: string,
|
|
338
|
+
number: number,
|
|
339
|
+
value: ValueCodec<unknown>,
|
|
340
|
+
optional = false,
|
|
341
|
+
): CompiledField {
|
|
342
|
+
return {
|
|
343
|
+
number,
|
|
344
|
+
initDefault(message) {
|
|
345
|
+
if (!optional && value.defaultValue !== undefined) {
|
|
346
|
+
Reflect.set(message, name, value.defaultValue);
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
encode(message, writer) {
|
|
350
|
+
const input = Reflect.get(message, name);
|
|
351
|
+
if (input === undefined || (!optional && value.isDefault(input))) return;
|
|
352
|
+
writer.tag(number, value.wireType);
|
|
353
|
+
value.encode(input, writer);
|
|
354
|
+
},
|
|
355
|
+
decode(message, reader, wireType, _fieldNumber) {
|
|
356
|
+
assertWireType(wireType, value.wireType);
|
|
357
|
+
Reflect.set(message, name, value.decode(reader));
|
|
358
|
+
},
|
|
359
|
+
toJson(message, output) {
|
|
360
|
+
const input = Reflect.get(message, name);
|
|
361
|
+
if (input === undefined || (!optional && value.isDefault(input))) return;
|
|
362
|
+
output[name] = value.toJson(input);
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function compileRepeatedField(
|
|
368
|
+
name: string,
|
|
369
|
+
number: number,
|
|
370
|
+
value: ValueCodec<unknown>,
|
|
371
|
+
): CompiledField {
|
|
372
|
+
return {
|
|
373
|
+
number,
|
|
374
|
+
initDefault(message) {
|
|
375
|
+
Reflect.set(message, name, []);
|
|
376
|
+
},
|
|
377
|
+
encode(message, writer) {
|
|
378
|
+
const items = Reflect.get(message, name);
|
|
379
|
+
if (!Array.isArray(items) || items.length === 0) return;
|
|
380
|
+
|
|
381
|
+
if (value.wireType !== 2 && isPackableScalar(value)) {
|
|
382
|
+
const packed = new Writer();
|
|
383
|
+
for (const item of items) {
|
|
384
|
+
value.encode(item, packed);
|
|
385
|
+
}
|
|
386
|
+
writer.tag(number, 2);
|
|
387
|
+
writer.lengthDelimited(packed.finish());
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
for (const item of items) {
|
|
392
|
+
writer.tag(number, value.wireType);
|
|
393
|
+
value.encode(item, writer);
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
decode(message, reader, wireType, _fieldNumber) {
|
|
397
|
+
const target = arrayField(message, name);
|
|
398
|
+
if (wireType === 2 && value.wireType !== 2 && isPackableScalar(value)) {
|
|
399
|
+
const limit = reader.uint32();
|
|
400
|
+
const end = reader.pos + limit;
|
|
401
|
+
while (reader.pos < end) {
|
|
402
|
+
target.push(value.decode(reader));
|
|
403
|
+
}
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
assertWireType(wireType, value.wireType);
|
|
407
|
+
target.push(value.decode(reader));
|
|
408
|
+
},
|
|
409
|
+
toJson(message, output) {
|
|
410
|
+
const items = Reflect.get(message, name);
|
|
411
|
+
if (!Array.isArray(items) || items.length === 0) return;
|
|
412
|
+
output[name] = items.map((item) => value.toJson(item));
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function compileMapField(desc: MapFieldDesc): CompiledField {
|
|
418
|
+
const name = desc.name;
|
|
419
|
+
const number = desc.no;
|
|
420
|
+
const key = scalarValue("string");
|
|
421
|
+
const valCodec =
|
|
422
|
+
typeof desc.V === "function" ? messageValue(desc.V) : scalarValue(desc.V);
|
|
423
|
+
|
|
424
|
+
return {
|
|
425
|
+
number,
|
|
426
|
+
initDefault(message) {
|
|
427
|
+
Reflect.set(message, name, Object.create(null));
|
|
428
|
+
},
|
|
429
|
+
encode(message, writer) {
|
|
430
|
+
const input = Reflect.get(message, name);
|
|
431
|
+
if (!isMessageObject(input)) return;
|
|
432
|
+
for (const entryKey in input) {
|
|
433
|
+
const entry = new Writer();
|
|
434
|
+
if (!key.isDefault(entryKey)) {
|
|
435
|
+
entry.tag(1, key.wireType);
|
|
436
|
+
key.encode(entryKey, entry);
|
|
437
|
+
}
|
|
438
|
+
const entryValue = input[entryKey];
|
|
439
|
+
if (!valCodec.isDefault(entryValue)) {
|
|
440
|
+
entry.tag(2, valCodec.wireType);
|
|
441
|
+
valCodec.encode(entryValue, entry);
|
|
442
|
+
}
|
|
443
|
+
writer.tag(number, 2);
|
|
444
|
+
writer.lengthDelimited(entry.finish());
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
decode(message, reader, wireType, _fieldNumber) {
|
|
448
|
+
assertWireType(wireType, 2);
|
|
449
|
+
const target = mapField(message, name);
|
|
450
|
+
const limit = reader.uint32();
|
|
451
|
+
const end = reader.pos + limit;
|
|
452
|
+
let entryKey = "";
|
|
453
|
+
let entryValue: unknown = valCodec.defaultValue;
|
|
454
|
+
|
|
455
|
+
while (reader.pos < end) {
|
|
456
|
+
const tag = reader.uint32();
|
|
457
|
+
const entryNumber = tag >>> 3;
|
|
458
|
+
const entryWireType = tag & 7;
|
|
459
|
+
if (!isWireType(entryWireType)) {
|
|
460
|
+
throw new Error(
|
|
461
|
+
`Unsupported wire type ${entryWireType} in map entry`,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
if (entryNumber === 1) {
|
|
465
|
+
assertWireType(entryWireType, key.wireType);
|
|
466
|
+
entryKey = requireString(key.decode(reader));
|
|
467
|
+
} else if (entryNumber === 2) {
|
|
468
|
+
assertWireType(entryWireType, valCodec.wireType);
|
|
469
|
+
entryValue = valCodec.decode(reader);
|
|
470
|
+
} else {
|
|
471
|
+
reader.skip(entryWireType);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
target[entryKey] = entryValue;
|
|
476
|
+
},
|
|
477
|
+
toJson(message, output) {
|
|
478
|
+
const input = Reflect.get(message, name);
|
|
479
|
+
if (!isMessageObject(input)) return;
|
|
480
|
+
const mapOutput: { [key: string]: JsonValue } = Object.create(null);
|
|
481
|
+
for (const entryKey in input) {
|
|
482
|
+
mapOutput[entryKey] = valCodec.toJson(input[entryKey]);
|
|
483
|
+
}
|
|
484
|
+
output[name] = mapOutput;
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function compileOneofField(desc: OneofFieldDesc): CompiledField {
|
|
490
|
+
const name = desc.name;
|
|
491
|
+
const variantsByName = new Map<
|
|
492
|
+
string,
|
|
493
|
+
{ no: number; codec: ValueCodec<unknown> }
|
|
494
|
+
>();
|
|
495
|
+
const variantsByNumber = new Map<
|
|
496
|
+
number,
|
|
497
|
+
{ name: string; codec: ValueCodec<unknown> }
|
|
498
|
+
>();
|
|
499
|
+
|
|
500
|
+
for (const variant of desc.variants) {
|
|
501
|
+
const codec =
|
|
502
|
+
variant.kind === "message"
|
|
503
|
+
? messageValue(variant.T)
|
|
504
|
+
: scalarValue(variant.kind);
|
|
505
|
+
variantsByName.set(variant.name, { no: variant.no, codec });
|
|
506
|
+
variantsByNumber.set(variant.no, { name: variant.name, codec });
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return {
|
|
510
|
+
number: 0,
|
|
511
|
+
initDefault(message) {
|
|
512
|
+
Reflect.set(message, name, { case: undefined });
|
|
513
|
+
},
|
|
514
|
+
encode(message, writer) {
|
|
515
|
+
const oneof = Reflect.get(message, name);
|
|
516
|
+
if (
|
|
517
|
+
!oneof ||
|
|
518
|
+
typeof oneof !== "object" ||
|
|
519
|
+
!("case" in oneof) ||
|
|
520
|
+
typeof oneof.case !== "string"
|
|
521
|
+
)
|
|
522
|
+
return;
|
|
523
|
+
const variant = variantsByName.get(oneof.case);
|
|
524
|
+
if (!variant) return;
|
|
525
|
+
const value = Reflect.get(oneof, "value");
|
|
526
|
+
if (value === undefined) return;
|
|
527
|
+
writer.tag(variant.no, variant.codec.wireType);
|
|
528
|
+
variant.codec.encode(value, writer);
|
|
529
|
+
},
|
|
530
|
+
decode(message, reader, wireType, fieldNumber) {
|
|
531
|
+
const variant = variantsByNumber.get(fieldNumber);
|
|
532
|
+
if (!variant) throw new Error(`Unknown oneof field ${fieldNumber}`);
|
|
533
|
+
assertWireType(wireType, variant.codec.wireType);
|
|
534
|
+
Reflect.set(message, name, {
|
|
535
|
+
case: variant.name,
|
|
536
|
+
value: variant.codec.decode(reader),
|
|
537
|
+
});
|
|
538
|
+
},
|
|
539
|
+
toJson(message, output) {
|
|
540
|
+
const oneof = Reflect.get(message, name);
|
|
541
|
+
if (
|
|
542
|
+
!oneof ||
|
|
543
|
+
typeof oneof !== "object" ||
|
|
544
|
+
!("case" in oneof) ||
|
|
545
|
+
typeof oneof.case !== "string"
|
|
546
|
+
)
|
|
547
|
+
return;
|
|
548
|
+
const variant = variantsByName.get(oneof.case);
|
|
549
|
+
if (!variant) return;
|
|
550
|
+
const value = Reflect.get(oneof, "value");
|
|
551
|
+
if (value === undefined) return;
|
|
552
|
+
output[oneof.case] = variant.codec.toJson(value);
|
|
553
|
+
},
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
function isPackableScalar(value: ValueCodec<unknown>): boolean {
|
|
558
|
+
return value.wireType === 0 || value.wireType === 1 || value.wireType === 5;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function scalarValue(kind: ScalarKind): ValueCodec<unknown> {
|
|
562
|
+
switch (kind) {
|
|
563
|
+
case "bool":
|
|
564
|
+
return scalar(
|
|
565
|
+
0,
|
|
566
|
+
false,
|
|
567
|
+
requireBoolean,
|
|
568
|
+
(value, writer) => writer.bool(value),
|
|
569
|
+
(reader) => reader.bool(),
|
|
570
|
+
(value) => value,
|
|
571
|
+
);
|
|
572
|
+
case "bytes":
|
|
573
|
+
return scalar(
|
|
574
|
+
2,
|
|
575
|
+
new Uint8Array(0),
|
|
576
|
+
requireBytes,
|
|
577
|
+
(value, writer) => writer.bytes(value),
|
|
578
|
+
(reader) => reader.bytes(),
|
|
579
|
+
(value) => Buffer.from(value).toString("base64"),
|
|
580
|
+
(value) => value.byteLength === 0,
|
|
581
|
+
);
|
|
582
|
+
case "double":
|
|
583
|
+
return scalar(
|
|
584
|
+
1,
|
|
585
|
+
0,
|
|
586
|
+
requireNumber,
|
|
587
|
+
(value, writer) => writer.double(value),
|
|
588
|
+
(reader) => reader.double(),
|
|
589
|
+
(value) => value,
|
|
590
|
+
);
|
|
591
|
+
case "enum":
|
|
592
|
+
return scalar(
|
|
593
|
+
0,
|
|
594
|
+
0,
|
|
595
|
+
requireInt32,
|
|
596
|
+
(value, writer) => writer.int32(value),
|
|
597
|
+
(reader) => reader.int32(),
|
|
598
|
+
(value) => value,
|
|
599
|
+
);
|
|
600
|
+
case "float":
|
|
601
|
+
return scalar(
|
|
602
|
+
5,
|
|
603
|
+
0,
|
|
604
|
+
requireNumber,
|
|
605
|
+
(value, writer) => writer.float(value),
|
|
606
|
+
(reader) => reader.float(),
|
|
607
|
+
(value) => value,
|
|
608
|
+
);
|
|
609
|
+
case "int32":
|
|
610
|
+
return scalar(
|
|
611
|
+
0,
|
|
612
|
+
0,
|
|
613
|
+
requireInt32,
|
|
614
|
+
(value, writer) => writer.int32(value),
|
|
615
|
+
(reader) => reader.int32(),
|
|
616
|
+
(value) => value,
|
|
617
|
+
);
|
|
618
|
+
case "int64":
|
|
619
|
+
return scalar(
|
|
620
|
+
0,
|
|
621
|
+
0n,
|
|
622
|
+
requireBigInt,
|
|
623
|
+
(value, writer) => writer.int64(value),
|
|
624
|
+
(reader) => reader.int64(),
|
|
625
|
+
(value) => value.toString(),
|
|
626
|
+
);
|
|
627
|
+
case "string":
|
|
628
|
+
return scalar(
|
|
629
|
+
2,
|
|
630
|
+
"",
|
|
631
|
+
requireString,
|
|
632
|
+
(value, writer) => writer.string(value),
|
|
633
|
+
(reader) => reader.string(),
|
|
634
|
+
(value) => value,
|
|
635
|
+
);
|
|
636
|
+
case "uint32":
|
|
637
|
+
return scalar(
|
|
638
|
+
0,
|
|
639
|
+
0,
|
|
640
|
+
requireUint32,
|
|
641
|
+
(value, writer) => writer.uint32(value),
|
|
642
|
+
(reader) => reader.uint32(),
|
|
643
|
+
(value) => value,
|
|
644
|
+
);
|
|
645
|
+
case "uint64":
|
|
646
|
+
return scalar(
|
|
647
|
+
0,
|
|
648
|
+
0n,
|
|
649
|
+
requireUnsignedBigInt,
|
|
650
|
+
(value, writer) => writer.uint64(value),
|
|
651
|
+
(reader) => reader.uint64(),
|
|
652
|
+
(value) => value.toString(),
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
function scalar<TValue>(
|
|
658
|
+
wireType: WireType,
|
|
659
|
+
defaultValue: TValue,
|
|
660
|
+
validate: (value: unknown) => TValue,
|
|
661
|
+
write: (value: TValue, writer: Writer) => void,
|
|
662
|
+
read: (reader: Reader) => TValue,
|
|
663
|
+
toJson: (value: TValue) => JsonValue,
|
|
664
|
+
isDefault: (value: TValue) => boolean = (value) => value === defaultValue,
|
|
665
|
+
): ValueCodec<TValue> {
|
|
666
|
+
return {
|
|
667
|
+
wireType,
|
|
668
|
+
defaultValue,
|
|
669
|
+
encode(value, writer) {
|
|
670
|
+
write(validate(value), writer);
|
|
671
|
+
},
|
|
672
|
+
decode(reader) {
|
|
673
|
+
return read(reader);
|
|
674
|
+
},
|
|
675
|
+
toJson(value) {
|
|
676
|
+
return toJson(validate(value));
|
|
677
|
+
},
|
|
678
|
+
isDefault(value) {
|
|
679
|
+
return isDefault(validate(value));
|
|
680
|
+
},
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
function messageValue(factory: () => MessageReference): ValueCodec<unknown> {
|
|
685
|
+
let cached: MessageReference | undefined;
|
|
686
|
+
|
|
687
|
+
function getCodec(): MessageReference {
|
|
688
|
+
if (!cached) cached = factory();
|
|
689
|
+
return cached;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
return {
|
|
693
|
+
wireType: 2,
|
|
694
|
+
defaultValue: undefined,
|
|
695
|
+
encode(value, writer) {
|
|
696
|
+
writer.lengthDelimited(getCodec().encode(value));
|
|
697
|
+
},
|
|
698
|
+
decode(reader) {
|
|
699
|
+
return getCodec().decode(reader.bytes());
|
|
700
|
+
},
|
|
701
|
+
toJson(value) {
|
|
702
|
+
return getCodec().toJson(value);
|
|
703
|
+
},
|
|
704
|
+
isDefault(value) {
|
|
705
|
+
return value === undefined;
|
|
706
|
+
},
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
function requireBoolean(value: unknown): boolean {
|
|
711
|
+
if (typeof value === "boolean") return value;
|
|
712
|
+
throw new Error(`Expected boolean, got ${typeof value}`);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function requireBytes(value: unknown): Uint8Array {
|
|
716
|
+
if (value instanceof Uint8Array) return value;
|
|
717
|
+
throw new Error("Expected Uint8Array");
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
function requireNumber(value: unknown): number {
|
|
721
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
722
|
+
throw new Error(`Expected number, got ${typeof value}`);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
function requireInt32(value: unknown): number {
|
|
726
|
+
if (typeof value === "number" && Number.isInteger(value)) return value | 0;
|
|
727
|
+
throw new Error(`Expected int32, got ${typeof value}`);
|
|
728
|
+
}
|
|
729
|
+
function requireString(value: unknown): string {
|
|
730
|
+
if (typeof value === "string") return value;
|
|
731
|
+
throw new Error(`Expected string, got ${typeof value}`);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
function requireBigInt(value: unknown): bigint {
|
|
735
|
+
if (typeof value === "bigint") return value;
|
|
736
|
+
if (typeof value === "number" && Number.isInteger(value))
|
|
737
|
+
return BigInt(value);
|
|
738
|
+
if (typeof value === "string") return BigInt(value);
|
|
739
|
+
throw new Error(`Expected bigint, got ${typeof value}`);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
function requireUint32(value: unknown): number {
|
|
743
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= 0)
|
|
744
|
+
return value >>> 0;
|
|
745
|
+
throw new Error(`Expected uint32, got ${typeof value}`);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
function requireUnsignedBigInt(value: unknown): bigint {
|
|
749
|
+
const b = requireBigInt(value);
|
|
750
|
+
if (b < 0n) throw new Error("Expected unsigned bigint");
|
|
751
|
+
return b;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
function arrayField(message: object, name: string): unknown[] {
|
|
755
|
+
let arr = Reflect.get(message, name);
|
|
756
|
+
if (!Array.isArray(arr)) {
|
|
757
|
+
arr = [];
|
|
758
|
+
Reflect.set(message, name, arr);
|
|
759
|
+
}
|
|
760
|
+
return arr;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
function mapField(message: object, name: string): Record<string, unknown> {
|
|
764
|
+
const value = Reflect.get(message, name);
|
|
765
|
+
if (isRecord(value)) return value;
|
|
766
|
+
const map: Record<string, unknown> = Object.create(null);
|
|
767
|
+
Reflect.set(message, name, map);
|
|
768
|
+
return map;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
function appendUnknownField(message: object, field: ProtoUnknownField): void {
|
|
772
|
+
const existing = Reflect.get(message, "$unknown");
|
|
773
|
+
if (isUnknownFields(existing)) {
|
|
774
|
+
existing.push(field);
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
Reflect.set(message, "$unknown", [field]);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
function isUnknownFields(value: unknown): value is ProtoUnknownField[] {
|
|
781
|
+
return Array.isArray(value) && value.every(isUnknownField);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function writeUnknownFields(message: object, writer: Writer): void {
|
|
785
|
+
const bag = Reflect.get(message, "$unknown");
|
|
786
|
+
if (!Array.isArray(bag)) return;
|
|
787
|
+
for (const field of bag) {
|
|
788
|
+
if (isUnknownField(field)) {
|
|
789
|
+
writer.tag(field.no, field.wireType);
|
|
790
|
+
writer.raw(field.data);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
function isUnknownField(
|
|
796
|
+
value: unknown,
|
|
797
|
+
): value is ProtoUnknownField & { wireType: WireType } {
|
|
798
|
+
return (
|
|
799
|
+
isRecord(value) &&
|
|
800
|
+
typeof value.no === "number" &&
|
|
801
|
+
typeof value.wireType === "number" &&
|
|
802
|
+
isWireType(value.wireType) &&
|
|
803
|
+
value.data instanceof Uint8Array
|
|
804
|
+
);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
function isMessageObject(value: unknown): value is { [key: string]: unknown } {
|
|
808
|
+
return isRecord(value) && !(value instanceof Uint8Array);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
function isWireType(value: number): value is WireType {
|
|
812
|
+
return value === 0 || value === 1 || value === 2 || value === 5;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function assertWireType(actual: WireType, expected: WireType): void {
|
|
816
|
+
if (actual !== expected)
|
|
817
|
+
throw new Error(
|
|
818
|
+
`Unexpected protobuf wire type ${actual}; expected ${expected}`,
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
class Writer {
|
|
823
|
+
#chunks: Uint8Array[] = [];
|
|
824
|
+
#length = 0;
|
|
825
|
+
|
|
826
|
+
tag(number: number, wireType: WireType): void {
|
|
827
|
+
this.uint32((number << 3) | wireType);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
uint32(value: number): void {
|
|
831
|
+
let v = value >>> 0;
|
|
832
|
+
const buffer = new Uint8Array(5);
|
|
833
|
+
let pos = 0;
|
|
834
|
+
while (v > 0x7f) {
|
|
835
|
+
buffer[pos++] = (v & 0x7f) | 0x80;
|
|
836
|
+
v >>>= 7;
|
|
837
|
+
}
|
|
838
|
+
buffer[pos++] = v;
|
|
839
|
+
this.raw(buffer.subarray(0, pos));
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
int32(value: number): void {
|
|
843
|
+
if (value >= 0) {
|
|
844
|
+
this.uint32(value);
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
this.int64(BigInt(value));
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
int64(value: bigint): void {
|
|
851
|
+
let v = BigInt.asUintN(64, value);
|
|
852
|
+
const buffer = new Uint8Array(10);
|
|
853
|
+
let pos = 0;
|
|
854
|
+
while (v > 0x7fn) {
|
|
855
|
+
buffer[pos++] = Number(v & 0x7fn) | 0x80;
|
|
856
|
+
v >>= 7n;
|
|
857
|
+
}
|
|
858
|
+
buffer[pos++] = Number(v);
|
|
859
|
+
this.raw(buffer.subarray(0, pos));
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
uint64(value: bigint): void {
|
|
863
|
+
this.int64(value);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
bool(value: boolean): void {
|
|
867
|
+
this.raw(new Uint8Array([value ? 1 : 0]));
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
float(value: number): void {
|
|
871
|
+
const buffer = new Uint8Array(4);
|
|
872
|
+
new DataView(buffer.buffer).setFloat32(0, value, true);
|
|
873
|
+
this.raw(buffer);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
double(value: number): void {
|
|
877
|
+
const buffer = new Uint8Array(8);
|
|
878
|
+
new DataView(buffer.buffer).setFloat64(0, value, true);
|
|
879
|
+
this.raw(buffer);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
string(value: string): void {
|
|
883
|
+
this.lengthDelimited(textEncoder.encode(value));
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
bytes(value: Uint8Array): void {
|
|
887
|
+
this.lengthDelimited(value);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
lengthDelimited(value: Uint8Array): void {
|
|
891
|
+
this.uint32(value.byteLength);
|
|
892
|
+
this.raw(value);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
raw(chunk: Uint8Array): void {
|
|
896
|
+
this.#chunks.push(chunk);
|
|
897
|
+
this.#length += chunk.byteLength;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
finish(): Uint8Array {
|
|
901
|
+
if (this.#chunks.length === 1) return this.#chunks[0];
|
|
902
|
+
const result = new Uint8Array(this.#length);
|
|
903
|
+
let offset = 0;
|
|
904
|
+
for (const chunk of this.#chunks) {
|
|
905
|
+
result.set(chunk, offset);
|
|
906
|
+
offset += chunk.byteLength;
|
|
907
|
+
}
|
|
908
|
+
return result;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
class Reader {
|
|
913
|
+
readonly buf: Uint8Array;
|
|
914
|
+
readonly len: number;
|
|
915
|
+
pos = 0;
|
|
916
|
+
|
|
917
|
+
constructor(buf: Uint8Array) {
|
|
918
|
+
this.buf = buf;
|
|
919
|
+
this.len = buf.byteLength;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
uint32(): number {
|
|
923
|
+
let result = 0;
|
|
924
|
+
let shift = 0;
|
|
925
|
+
while (this.pos < this.len) {
|
|
926
|
+
const byte = this.buf[this.pos++];
|
|
927
|
+
result |= (byte & 0x7f) << shift;
|
|
928
|
+
if ((byte & 0x80) === 0) return result >>> 0;
|
|
929
|
+
shift += 7;
|
|
930
|
+
if (shift >= 32) throw new Error("Varint exceeds 32 bits");
|
|
931
|
+
}
|
|
932
|
+
throw new Error("Unexpected end of protobuf varint");
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
int32(): number {
|
|
936
|
+
return Number(BigInt.asIntN(32, this.uint64()));
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
int64(): bigint {
|
|
940
|
+
let result = 0n;
|
|
941
|
+
let shift = 0n;
|
|
942
|
+
while (this.pos < this.len) {
|
|
943
|
+
const byte = this.buf[this.pos++];
|
|
944
|
+
result |= BigInt(byte & 0x7f) << shift;
|
|
945
|
+
if ((byte & 0x80) === 0) return BigInt.asIntN(64, result);
|
|
946
|
+
shift += 7n;
|
|
947
|
+
if (shift >= 64n) throw new Error("Varint exceeds 64 bits");
|
|
948
|
+
}
|
|
949
|
+
throw new Error("Unexpected end of protobuf 64-bit varint");
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
uint64(): bigint {
|
|
953
|
+
return BigInt.asUintN(64, this.int64());
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
bool(): boolean {
|
|
957
|
+
return this.uint32() !== 0;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
float(): number {
|
|
961
|
+
if (this.pos + 4 > this.len)
|
|
962
|
+
throw new Error("Unexpected EOF reading float");
|
|
963
|
+
const view = new DataView(
|
|
964
|
+
this.buf.buffer,
|
|
965
|
+
this.buf.byteOffset + this.pos,
|
|
966
|
+
4,
|
|
967
|
+
);
|
|
968
|
+
this.pos += 4;
|
|
969
|
+
return view.getFloat32(0, true);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
double(): number {
|
|
973
|
+
if (this.pos + 8 > this.len)
|
|
974
|
+
throw new Error("Unexpected EOF reading double");
|
|
975
|
+
const view = new DataView(
|
|
976
|
+
this.buf.buffer,
|
|
977
|
+
this.buf.byteOffset + this.pos,
|
|
978
|
+
8,
|
|
979
|
+
);
|
|
980
|
+
this.pos += 8;
|
|
981
|
+
return view.getFloat64(0, true);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
string(): string {
|
|
985
|
+
return textDecoder.decode(this.bytes());
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
bytes(): Uint8Array {
|
|
989
|
+
const length = this.uint32();
|
|
990
|
+
if (this.pos + length > this.len)
|
|
991
|
+
throw new Error("Unexpected EOF reading bytes");
|
|
992
|
+
const result = this.buf.subarray(this.pos, this.pos + length);
|
|
993
|
+
this.pos += length;
|
|
994
|
+
return result;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
slice(start: number, end: number): Uint8Array {
|
|
998
|
+
return this.buf.subarray(start, end);
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
skip(wireType: WireType): void {
|
|
1002
|
+
switch (wireType) {
|
|
1003
|
+
case 0:
|
|
1004
|
+
this.int64();
|
|
1005
|
+
return;
|
|
1006
|
+
case 1:
|
|
1007
|
+
if (this.pos + 8 > this.len)
|
|
1008
|
+
throw new Error("Unexpected EOF skipping 64-bit");
|
|
1009
|
+
this.pos += 8;
|
|
1010
|
+
return;
|
|
1011
|
+
case 2:
|
|
1012
|
+
this.bytes();
|
|
1013
|
+
return;
|
|
1014
|
+
case 5:
|
|
1015
|
+
if (this.pos + 4 > this.len)
|
|
1016
|
+
throw new Error("Unexpected EOF skipping 32-bit");
|
|
1017
|
+
this.pos += 4;
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
function writeJsonValue(writer: Writer, value: JsonValue): void {
|
|
1024
|
+
if (value === null) {
|
|
1025
|
+
writer.tag(1, 0);
|
|
1026
|
+
writer.uint32(0);
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
if (typeof value === "number") {
|
|
1030
|
+
writer.tag(2, 1);
|
|
1031
|
+
writer.double(value);
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
if (typeof value === "string") {
|
|
1035
|
+
writer.tag(3, 2);
|
|
1036
|
+
writer.string(value);
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
if (typeof value === "boolean") {
|
|
1040
|
+
writer.tag(4, 0);
|
|
1041
|
+
writer.bool(value);
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
if (Array.isArray(value)) {
|
|
1045
|
+
const listWriter = new Writer();
|
|
1046
|
+
for (const item of value) {
|
|
1047
|
+
listWriter.tag(1, 2);
|
|
1048
|
+
const itemWriter = new Writer();
|
|
1049
|
+
writeJsonValue(itemWriter, item);
|
|
1050
|
+
listWriter.lengthDelimited(itemWriter.finish());
|
|
1051
|
+
}
|
|
1052
|
+
writer.tag(6, 2);
|
|
1053
|
+
writer.lengthDelimited(listWriter.finish());
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
if (isRecord(value)) {
|
|
1057
|
+
const structWriter = new Writer();
|
|
1058
|
+
for (const key in value) {
|
|
1059
|
+
const item = value[key];
|
|
1060
|
+
const entryWriter = new Writer();
|
|
1061
|
+
entryWriter.tag(1, 2);
|
|
1062
|
+
entryWriter.string(key);
|
|
1063
|
+
entryWriter.tag(2, 2);
|
|
1064
|
+
const valueWriter = new Writer();
|
|
1065
|
+
writeJsonValue(valueWriter, item);
|
|
1066
|
+
entryWriter.lengthDelimited(valueWriter.finish());
|
|
1067
|
+
structWriter.tag(1, 2);
|
|
1068
|
+
structWriter.lengthDelimited(entryWriter.finish());
|
|
1069
|
+
}
|
|
1070
|
+
writer.tag(5, 2);
|
|
1071
|
+
writer.lengthDelimited(structWriter.finish());
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
function readJsonValue(reader: Reader): JsonValue {
|
|
1076
|
+
let value: JsonValue = null;
|
|
1077
|
+
while (reader.pos < reader.len) {
|
|
1078
|
+
const tag = reader.uint32();
|
|
1079
|
+
const fieldNumber = tag >>> 3;
|
|
1080
|
+
const wireType = tag & 7;
|
|
1081
|
+
if (!isWireType(wireType)) {
|
|
1082
|
+
throw new Error(
|
|
1083
|
+
`Unsupported wire type ${wireType} in google.protobuf.Value`,
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
switch (fieldNumber) {
|
|
1087
|
+
case 1:
|
|
1088
|
+
assertWireType(wireType, 0);
|
|
1089
|
+
reader.uint32();
|
|
1090
|
+
value = null;
|
|
1091
|
+
break;
|
|
1092
|
+
case 2:
|
|
1093
|
+
assertWireType(wireType, 1);
|
|
1094
|
+
value = reader.double();
|
|
1095
|
+
break;
|
|
1096
|
+
case 3:
|
|
1097
|
+
assertWireType(wireType, 2);
|
|
1098
|
+
value = reader.string();
|
|
1099
|
+
break;
|
|
1100
|
+
case 4:
|
|
1101
|
+
assertWireType(wireType, 0);
|
|
1102
|
+
value = reader.bool();
|
|
1103
|
+
break;
|
|
1104
|
+
case 5:
|
|
1105
|
+
assertWireType(wireType, 2);
|
|
1106
|
+
value = readJsonStruct(new Reader(reader.bytes()));
|
|
1107
|
+
break;
|
|
1108
|
+
case 6:
|
|
1109
|
+
assertWireType(wireType, 2);
|
|
1110
|
+
value = readJsonList(new Reader(reader.bytes()));
|
|
1111
|
+
break;
|
|
1112
|
+
default:
|
|
1113
|
+
reader.skip(wireType);
|
|
1114
|
+
break;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
return value;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
function readJsonStruct(reader: Reader): { [key: string]: JsonValue } {
|
|
1121
|
+
const output: { [key: string]: JsonValue } = {};
|
|
1122
|
+
while (reader.pos < reader.len) {
|
|
1123
|
+
const tag = reader.uint32();
|
|
1124
|
+
const fieldNumber = tag >>> 3;
|
|
1125
|
+
const wireType = tag & 7;
|
|
1126
|
+
if (!isWireType(wireType)) {
|
|
1127
|
+
throw new Error(`Unsupported wire type ${wireType} in Struct`);
|
|
1128
|
+
}
|
|
1129
|
+
if (fieldNumber === 1) {
|
|
1130
|
+
assertWireType(wireType, 2);
|
|
1131
|
+
const entryReader = new Reader(reader.bytes());
|
|
1132
|
+
let entryKey = "";
|
|
1133
|
+
let entryVal: JsonValue = null;
|
|
1134
|
+
while (entryReader.pos < entryReader.len) {
|
|
1135
|
+
const entryTag = entryReader.uint32();
|
|
1136
|
+
const entryNo = entryTag >>> 3;
|
|
1137
|
+
const entryWire = entryTag & 7;
|
|
1138
|
+
if (entryNo === 1) {
|
|
1139
|
+
entryKey = entryReader.string();
|
|
1140
|
+
} else if (entryNo === 2) {
|
|
1141
|
+
entryVal = readJsonValue(new Reader(entryReader.bytes()));
|
|
1142
|
+
} else if (isWireType(entryWire)) {
|
|
1143
|
+
entryReader.skip(entryWire);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
output[entryKey] = entryVal;
|
|
1147
|
+
} else {
|
|
1148
|
+
reader.skip(wireType);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return output;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
function readJsonList(reader: Reader): JsonValue[] {
|
|
1155
|
+
const list: JsonValue[] = [];
|
|
1156
|
+
while (reader.pos < reader.len) {
|
|
1157
|
+
const tag = reader.uint32();
|
|
1158
|
+
const fieldNumber = tag >>> 3;
|
|
1159
|
+
const wireType = tag & 7;
|
|
1160
|
+
if (!isWireType(wireType)) {
|
|
1161
|
+
throw new Error(`Unsupported wire type ${wireType} in ListValue`);
|
|
1162
|
+
}
|
|
1163
|
+
if (fieldNumber === 1) {
|
|
1164
|
+
assertWireType(wireType, 2);
|
|
1165
|
+
list.push(readJsonValue(new Reader(reader.bytes())));
|
|
1166
|
+
} else {
|
|
1167
|
+
reader.skip(wireType);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
return list;
|
|
1171
|
+
}
|