@bufbuild/protobuf 1.5.1 → 1.7.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/dist/cjs/binary-encoding.js +2 -3
- package/dist/cjs/binary-format.d.ts +17 -0
- package/dist/cjs/binary-format.js +1 -1
- package/dist/cjs/codegen-info.d.ts +4 -4
- package/dist/cjs/codegen-info.js +2 -1
- package/dist/cjs/create-descriptor-set.d.ts +1 -1
- package/dist/cjs/create-descriptor-set.js +56 -50
- package/dist/cjs/create-registry-from-desc.d.ts +2 -2
- package/dist/cjs/create-registry-from-desc.js +53 -9
- package/dist/cjs/create-registry.d.ts +3 -2
- package/dist/cjs/create-registry.js +56 -37
- package/dist/cjs/descriptor-set.js +1 -1
- package/dist/cjs/enum.js +1 -1
- package/dist/cjs/extension-accessor.d.ts +35 -0
- package/dist/cjs/extension-accessor.js +108 -0
- package/dist/cjs/extension.d.ts +24 -0
- package/dist/cjs/extension.js +15 -0
- package/dist/cjs/field-list.js +1 -1
- package/dist/cjs/field.js +1 -1
- package/dist/cjs/google/protobuf/any_pb.js +1 -1
- package/dist/cjs/google/protobuf/api_pb.js +1 -1
- package/dist/cjs/google/protobuf/compiler/plugin_pb.js +1 -1
- package/dist/cjs/google/protobuf/descriptor_pb.js +2 -2
- package/dist/cjs/google/protobuf/duration_pb.js +1 -1
- package/dist/cjs/google/protobuf/empty_pb.js +1 -1
- package/dist/cjs/google/protobuf/field_mask_pb.js +1 -1
- package/dist/cjs/google/protobuf/source_context_pb.js +1 -1
- package/dist/cjs/google/protobuf/struct_pb.js +2 -2
- package/dist/cjs/google/protobuf/timestamp_pb.js +1 -1
- package/dist/cjs/google/protobuf/type_pb.js +2 -2
- package/dist/cjs/google/protobuf/wrappers_pb.js +1 -1
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/json-format.d.ts +5 -5
- package/dist/cjs/json-format.js +1 -1
- package/dist/cjs/message-type.js +1 -1
- package/dist/cjs/message.js +1 -1
- package/dist/cjs/private/assert.js +1 -1
- package/dist/cjs/private/binary-format-common.d.ts +2 -3
- package/dist/cjs/private/binary-format-common.js +80 -78
- package/dist/cjs/private/binary-format-proto2.js +59 -64
- package/dist/cjs/private/binary-format-proto3.js +44 -40
- package/dist/cjs/private/enum.js +1 -1
- package/dist/cjs/private/extensions.d.ts +34 -0
- package/dist/cjs/private/extensions.js +86 -0
- package/dist/cjs/private/feature-set.d.ts +3 -3
- package/dist/cjs/private/feature-set.js +27 -32
- package/dist/cjs/private/field-list.js +1 -1
- package/dist/cjs/private/field-wrapper.d.ts +2 -2
- package/dist/cjs/private/field-wrapper.js +1 -1
- package/dist/cjs/private/field.js +1 -1
- package/dist/cjs/private/json-format-common.js +202 -156
- package/dist/cjs/private/json-format-proto2.js +2 -1
- package/dist/cjs/private/json-format-proto3.js +7 -5
- package/dist/cjs/private/message-type.js +1 -1
- package/dist/cjs/private/names.d.ts +2 -2
- package/dist/cjs/private/names.js +3 -2
- package/dist/cjs/private/options-map.js +1 -1
- package/dist/cjs/private/proto-runtime.d.ts +6 -0
- package/dist/cjs/private/proto-runtime.js +5 -1
- package/dist/cjs/private/reify-wkt.js +1 -1
- package/dist/cjs/private/scalars.js +1 -1
- package/dist/cjs/private/text-format.js +1 -1
- package/dist/cjs/private/util-common.js +1 -1
- package/dist/cjs/private/util.js +1 -1
- package/dist/cjs/proto-base64.js +1 -1
- package/dist/cjs/proto-delimited.js +1 -1
- package/dist/cjs/proto-double.js +1 -1
- package/dist/cjs/proto-int64.js +1 -1
- package/dist/cjs/proto2.js +1 -1
- package/dist/cjs/proto3.js +1 -1
- package/dist/cjs/service-type.js +1 -1
- package/dist/cjs/to-plain-message.js +1 -1
- package/dist/cjs/type-registry.d.ts +14 -0
- package/dist/cjs/type-registry.js +1 -1
- package/dist/esm/binary-encoding.js +2 -3
- package/dist/esm/binary-format.d.ts +17 -0
- package/dist/esm/binary-format.js +1 -1
- package/dist/esm/codegen-info.d.ts +4 -4
- package/dist/esm/codegen-info.js +2 -1
- package/dist/esm/create-descriptor-set.d.ts +1 -1
- package/dist/esm/create-descriptor-set.js +56 -50
- package/dist/esm/create-registry-from-desc.d.ts +2 -2
- package/dist/esm/create-registry-from-desc.js +53 -9
- package/dist/esm/create-registry.d.ts +3 -2
- package/dist/esm/create-registry.js +56 -37
- package/dist/esm/descriptor-set.js +1 -1
- package/dist/esm/enum.js +1 -1
- package/dist/esm/extension-accessor.d.ts +35 -0
- package/dist/esm/extension-accessor.js +101 -0
- package/dist/esm/extension.d.ts +24 -0
- package/dist/esm/extension.js +14 -0
- package/dist/esm/field-list.js +1 -1
- package/dist/esm/field.js +1 -1
- package/dist/esm/google/protobuf/any_pb.js +1 -1
- package/dist/esm/google/protobuf/api_pb.js +1 -1
- package/dist/esm/google/protobuf/compiler/plugin_pb.js +1 -1
- package/dist/esm/google/protobuf/descriptor_pb.js +2 -2
- package/dist/esm/google/protobuf/duration_pb.js +1 -1
- package/dist/esm/google/protobuf/empty_pb.js +1 -1
- package/dist/esm/google/protobuf/field_mask_pb.js +1 -1
- package/dist/esm/google/protobuf/source_context_pb.js +1 -1
- package/dist/esm/google/protobuf/struct_pb.js +2 -2
- package/dist/esm/google/protobuf/timestamp_pb.js +1 -1
- package/dist/esm/google/protobuf/type_pb.js +2 -2
- package/dist/esm/google/protobuf/wrappers_pb.js +1 -1
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/json-format.d.ts +5 -5
- package/dist/esm/json-format.js +1 -1
- package/dist/esm/message-type.js +1 -1
- package/dist/esm/message.js +1 -1
- package/dist/esm/private/assert.js +1 -1
- package/dist/esm/private/binary-format-common.d.ts +2 -3
- package/dist/esm/private/binary-format-common.js +80 -77
- package/dist/esm/private/binary-format-proto2.js +59 -64
- package/dist/esm/private/binary-format-proto3.js +44 -40
- package/dist/esm/private/enum.js +1 -1
- package/dist/esm/private/extensions.d.ts +34 -0
- package/dist/esm/private/extensions.js +81 -0
- package/dist/esm/private/feature-set.d.ts +3 -3
- package/dist/esm/private/feature-set.js +27 -32
- package/dist/esm/private/field-list.js +1 -1
- package/dist/esm/private/field-wrapper.d.ts +2 -2
- package/dist/esm/private/field-wrapper.js +1 -1
- package/dist/esm/private/field.js +1 -1
- package/dist/esm/private/json-format-common.js +202 -156
- package/dist/esm/private/json-format-proto2.js +2 -1
- package/dist/esm/private/json-format-proto3.js +7 -5
- package/dist/esm/private/message-type.js +1 -1
- package/dist/esm/private/names.d.ts +2 -2
- package/dist/esm/private/names.js +3 -2
- package/dist/esm/private/options-map.js +1 -1
- package/dist/esm/private/proto-runtime.d.ts +6 -0
- package/dist/esm/private/proto-runtime.js +5 -1
- package/dist/esm/private/reify-wkt.js +1 -1
- package/dist/esm/private/scalars.js +1 -1
- package/dist/esm/private/text-format.js +1 -1
- package/dist/esm/private/util-common.js +1 -1
- package/dist/esm/private/util.js +1 -1
- package/dist/esm/proto-base64.js +1 -1
- package/dist/esm/proto-delimited.js +1 -1
- package/dist/esm/proto-double.js +1 -1
- package/dist/esm/proto-int64.js +1 -1
- package/dist/esm/proto2.js +1 -1
- package/dist/esm/proto3.js +1 -1
- package/dist/esm/service-type.js +1 -1
- package/dist/esm/to-plain-message.js +1 -1
- package/dist/esm/type-registry.d.ts +14 -0
- package/dist/esm/type-registry.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2021-
|
|
1
|
+
// Copyright 2021-2024 Buf Technologies, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -21,7 +21,8 @@ export const featureSetDefaults = FeatureSetDefaults.fromBinary(protoBase64.dec(
|
|
|
21
21
|
/**
|
|
22
22
|
* Create an edition feature resolver with the given feature set defaults.
|
|
23
23
|
*/
|
|
24
|
-
export function createFeatureResolver(compiledFeatureSetDefaults) {
|
|
24
|
+
export function createFeatureResolver(compiledFeatureSetDefaults, edition) {
|
|
25
|
+
var _a, _b;
|
|
25
26
|
const min = compiledFeatureSetDefaults.minimumEdition;
|
|
26
27
|
const max = compiledFeatureSetDefaults.maximumEdition;
|
|
27
28
|
if (min === undefined ||
|
|
@@ -29,37 +30,31 @@ export function createFeatureResolver(compiledFeatureSetDefaults) {
|
|
|
29
30
|
compiledFeatureSetDefaults.defaults.some((d) => d.edition === undefined)) {
|
|
30
31
|
throw new Error("Invalid FeatureSetDefaults");
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (e > edition) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
if (highestMatch !== undefined && highestMatch.e > e) {
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
highestMatch = {
|
|
53
|
-
e,
|
|
54
|
-
f: (_b = c.features) !== null && _b !== void 0 ? _b : new FeatureSet(),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
if (highestMatch === undefined) {
|
|
58
|
-
throw new Error(`No valid default found for edition ${Edition[edition]}`);
|
|
59
|
-
}
|
|
60
|
-
defaultsBin = highestMatch.f.toBinary();
|
|
61
|
-
defaultsBinByEdition.set(edition, defaultsBin);
|
|
33
|
+
if (edition < min) {
|
|
34
|
+
throw new Error(`Edition ${Edition[edition]} is earlier than the minimum supported edition ${Edition[min]}`);
|
|
35
|
+
}
|
|
36
|
+
if (max < edition) {
|
|
37
|
+
throw new Error(`Edition ${Edition[edition]} is later than the maximum supported edition ${Edition[max]}`);
|
|
38
|
+
}
|
|
39
|
+
let highestMatch = undefined;
|
|
40
|
+
for (const c of compiledFeatureSetDefaults.defaults) {
|
|
41
|
+
const e = (_a = c.edition) !== null && _a !== void 0 ? _a : 0;
|
|
42
|
+
if (e > edition) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (highestMatch !== undefined && highestMatch.e > e) {
|
|
46
|
+
continue;
|
|
62
47
|
}
|
|
48
|
+
highestMatch = {
|
|
49
|
+
e,
|
|
50
|
+
f: (_b = c.features) !== null && _b !== void 0 ? _b : new FeatureSet(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (highestMatch === undefined) {
|
|
54
|
+
throw new Error(`No valid default found for edition ${Edition[edition]}`);
|
|
55
|
+
}
|
|
56
|
+
const defaultsBin = highestMatch.f.toBinary();
|
|
57
|
+
return (...rest) => {
|
|
63
58
|
const f = FeatureSet.fromBinary(defaultsBin);
|
|
64
59
|
for (const c of rest) {
|
|
65
60
|
if (c !== undefined) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Message } from "../message.js";
|
|
2
2
|
import type { MessageType } from "../message-type.js";
|
|
3
|
-
import type { DescField } from "../descriptor-set.js";
|
|
3
|
+
import type { DescExtension, DescField } from "../descriptor-set.js";
|
|
4
4
|
import { ScalarType } from "../field.js";
|
|
5
5
|
/**
|
|
6
6
|
* A field wrapper unwraps a message to a primitive value that is more
|
|
@@ -22,4 +22,4 @@ export declare function wrapField<T extends Message<T>>(type: MessageType<T>, va
|
|
|
22
22
|
* If the given field uses one of the well-known wrapper types, return
|
|
23
23
|
* the primitive type it wraps.
|
|
24
24
|
*/
|
|
25
|
-
export declare function getUnwrappedFieldType(field: DescField): ScalarType | undefined;
|
|
25
|
+
export declare function getUnwrappedFieldType(field: DescField | DescExtension): ScalarType | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2021-
|
|
1
|
+
// Copyright 2021-2024 Buf Technologies, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -16,6 +16,8 @@ import { LongType, ScalarType } from "../field.js";
|
|
|
16
16
|
import { assert, assertFloat32, assertInt32, assertUInt32 } from "./assert.js";
|
|
17
17
|
import { protoInt64 } from "../proto-int64.js";
|
|
18
18
|
import { protoBase64 } from "../proto-base64.js";
|
|
19
|
+
import { createExtensionContainer } from "./extensions.js";
|
|
20
|
+
import { getExtension, hasExtension, setExtension, } from "../extension-accessor.js";
|
|
19
21
|
/* eslint-disable no-case-declarations, @typescript-eslint/restrict-plus-operands,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument */
|
|
20
22
|
// Default options for parsing JSON.
|
|
21
23
|
const jsonReadDefaults = {
|
|
@@ -41,164 +43,45 @@ export function makeJsonFormatCommon(makeWriteField) {
|
|
|
41
43
|
makeWriteOptions,
|
|
42
44
|
readMessage(type, json, options, message) {
|
|
43
45
|
if (json == null || Array.isArray(json) || typeof json != "object") {
|
|
44
|
-
throw new Error(`cannot decode message ${type.typeName} from JSON: ${
|
|
46
|
+
throw new Error(`cannot decode message ${type.typeName} from JSON: ${debugJsonValue(json)}`);
|
|
45
47
|
}
|
|
46
48
|
message = message !== null && message !== void 0 ? message : new type();
|
|
47
|
-
const oneofSeen =
|
|
49
|
+
const oneofSeen = new Map();
|
|
50
|
+
const registry = options.typeRegistry;
|
|
48
51
|
for (const [jsonKey, jsonValue] of Object.entries(json)) {
|
|
49
52
|
const field = type.fields.findJsonName(jsonKey);
|
|
50
|
-
if (
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
let localName = field.localName;
|
|
57
|
-
let target = message;
|
|
58
|
-
if (field.oneof) {
|
|
59
|
-
if (jsonValue === null && field.kind == "scalar") {
|
|
60
|
-
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
const seen = oneofSeen[field.oneof.localName];
|
|
64
|
-
if (seen) {
|
|
65
|
-
throw new Error(`cannot decode message ${type.typeName} from JSON: multiple keys for oneof "${field.oneof.name}" present: "${seen}", "${jsonKey}"`);
|
|
66
|
-
}
|
|
67
|
-
oneofSeen[field.oneof.localName] = jsonKey;
|
|
68
|
-
target = target[field.oneof.localName] = { case: localName };
|
|
69
|
-
localName = "value";
|
|
70
|
-
}
|
|
71
|
-
if (field.repeated) {
|
|
72
|
-
if (jsonValue === null) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
if (!Array.isArray(jsonValue)) {
|
|
76
|
-
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`);
|
|
77
|
-
}
|
|
78
|
-
const targetArray = target[localName];
|
|
79
|
-
for (const jsonItem of jsonValue) {
|
|
80
|
-
if (jsonItem === null) {
|
|
81
|
-
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonItem)}`);
|
|
53
|
+
if (field) {
|
|
54
|
+
if (field.oneof) {
|
|
55
|
+
if (jsonValue === null && field.kind == "scalar") {
|
|
56
|
+
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
57
|
+
continue;
|
|
82
58
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
case "message":
|
|
87
|
-
val = field.T.fromJson(jsonItem, options);
|
|
88
|
-
break;
|
|
89
|
-
case "enum":
|
|
90
|
-
val = readEnum(field.T, jsonItem, options.ignoreUnknownFields);
|
|
91
|
-
if (val === undefined)
|
|
92
|
-
continue;
|
|
93
|
-
break;
|
|
94
|
-
case "scalar":
|
|
95
|
-
try {
|
|
96
|
-
val = readScalar(field.T, jsonItem, field.L);
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonItem)}`;
|
|
100
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
101
|
-
m += `: ${e.message}`;
|
|
102
|
-
}
|
|
103
|
-
throw new Error(m);
|
|
104
|
-
}
|
|
105
|
-
break;
|
|
59
|
+
const seen = oneofSeen.get(field.oneof);
|
|
60
|
+
if (seen !== undefined) {
|
|
61
|
+
throw new Error(`cannot decode message ${type.typeName} from JSON: multiple keys for oneof "${field.oneof.name}" present: "${seen}", "${jsonKey}"`);
|
|
106
62
|
}
|
|
107
|
-
|
|
63
|
+
oneofSeen.set(field.oneof, jsonKey);
|
|
108
64
|
}
|
|
65
|
+
readField(message, jsonValue, field, options, type);
|
|
109
66
|
}
|
|
110
|
-
else
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
case "message":
|
|
125
|
-
val = field.V.T.fromJson(jsonMapValue, options);
|
|
126
|
-
break;
|
|
127
|
-
case "enum":
|
|
128
|
-
val = readEnum(field.V.T, jsonMapValue, options.ignoreUnknownFields);
|
|
129
|
-
if (val === undefined)
|
|
130
|
-
continue;
|
|
131
|
-
break;
|
|
132
|
-
case "scalar":
|
|
133
|
-
try {
|
|
134
|
-
val = readScalar(field.V.T, jsonMapValue, LongType.BIGINT);
|
|
135
|
-
}
|
|
136
|
-
catch (e) {
|
|
137
|
-
let m = `cannot decode map value for field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`;
|
|
138
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
139
|
-
m += `: ${e.message}`;
|
|
140
|
-
}
|
|
141
|
-
throw new Error(m);
|
|
142
|
-
}
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
targetMap[readScalar(field.K, field.K == ScalarType.BOOL
|
|
147
|
-
? jsonMapKey == "true"
|
|
148
|
-
? true
|
|
149
|
-
: jsonMapKey == "false"
|
|
150
|
-
? false
|
|
151
|
-
: jsonMapKey
|
|
152
|
-
: jsonMapKey, LongType.BIGINT).toString()] = val;
|
|
153
|
-
}
|
|
154
|
-
catch (e) {
|
|
155
|
-
let m = `cannot decode map key for field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`;
|
|
156
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
157
|
-
m += `: ${e.message}`;
|
|
158
|
-
}
|
|
159
|
-
throw new Error(m);
|
|
67
|
+
else {
|
|
68
|
+
let found = false;
|
|
69
|
+
if ((registry === null || registry === void 0 ? void 0 : registry.findExtension) &&
|
|
70
|
+
jsonKey.startsWith("[") &&
|
|
71
|
+
jsonKey.endsWith("]")) {
|
|
72
|
+
const ext = registry.findExtension(jsonKey.substring(1, jsonKey.length - 1));
|
|
73
|
+
if (ext && ext.extendee.typeName == type.typeName) {
|
|
74
|
+
found = true;
|
|
75
|
+
const [container, get] = createExtensionContainer(ext);
|
|
76
|
+
readField(container, jsonValue, ext.field, options, ext);
|
|
77
|
+
// We pass on the options as BinaryReadOptions/BinaryWriteOptions,
|
|
78
|
+
// so that users can bring their own binary reader and writer factories
|
|
79
|
+
// if necessary.
|
|
80
|
+
setExtension(message, ext, get(), options);
|
|
160
81
|
}
|
|
161
82
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
switch (field.kind) {
|
|
165
|
-
case "message":
|
|
166
|
-
const messageType = field.T;
|
|
167
|
-
if (jsonValue === null &&
|
|
168
|
-
messageType.typeName != "google.protobuf.Value") {
|
|
169
|
-
if (field.oneof) {
|
|
170
|
-
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: null is invalid for oneof field "${jsonKey}"`);
|
|
171
|
-
}
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
if (target[localName] instanceof Message) {
|
|
175
|
-
target[localName].fromJson(jsonValue, options);
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
target[localName] = messageType.fromJson(jsonValue, options);
|
|
179
|
-
if (messageType.fieldWrapper && !field.oneof) {
|
|
180
|
-
target[localName] = messageType.fieldWrapper.unwrapField(target[localName]);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
break;
|
|
184
|
-
case "enum":
|
|
185
|
-
const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields);
|
|
186
|
-
if (enumValue !== undefined) {
|
|
187
|
-
target[localName] = enumValue;
|
|
188
|
-
}
|
|
189
|
-
break;
|
|
190
|
-
case "scalar":
|
|
191
|
-
try {
|
|
192
|
-
target[localName] = readScalar(field.T, jsonValue, field.L);
|
|
193
|
-
}
|
|
194
|
-
catch (e) {
|
|
195
|
-
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`;
|
|
196
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
197
|
-
m += `: ${e.message}`;
|
|
198
|
-
}
|
|
199
|
-
throw new Error(m);
|
|
200
|
-
}
|
|
201
|
-
break;
|
|
83
|
+
if (!found && !options.ignoreUnknownFields) {
|
|
84
|
+
throw new Error(`cannot decode message ${type.typeName} from JSON: key "${jsonKey}" is unknown`);
|
|
202
85
|
}
|
|
203
86
|
}
|
|
204
87
|
}
|
|
@@ -231,6 +114,21 @@ export function makeJsonFormatCommon(makeWriteField) {
|
|
|
231
114
|
jsonValue;
|
|
232
115
|
}
|
|
233
116
|
}
|
|
117
|
+
const registry = options.typeRegistry;
|
|
118
|
+
if (registry === null || registry === void 0 ? void 0 : registry.findExtensionFor) {
|
|
119
|
+
for (const uf of type.runtime.bin.listUnknownFields(message)) {
|
|
120
|
+
const ext = registry.findExtensionFor(type.typeName, uf.no);
|
|
121
|
+
if (ext && hasExtension(message, ext)) {
|
|
122
|
+
// We pass on the options as BinaryReadOptions, so that users can bring their own
|
|
123
|
+
// binary reader factory if necessary.
|
|
124
|
+
const value = getExtension(message, ext, options);
|
|
125
|
+
const jsonValue = writeField(ext.field, value, options);
|
|
126
|
+
if (jsonValue !== undefined) {
|
|
127
|
+
json[ext.field.jsonName] = jsonValue;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
234
132
|
}
|
|
235
133
|
catch (e) {
|
|
236
134
|
const m = field
|
|
@@ -259,6 +157,153 @@ function debugJsonValue(json) {
|
|
|
259
157
|
return String(json);
|
|
260
158
|
}
|
|
261
159
|
}
|
|
160
|
+
// Read a JSON value for a field.
|
|
161
|
+
// The "type" argument is only used to provide context in errors.
|
|
162
|
+
function readField(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
|
|
163
|
+
jsonValue, field, options, type) {
|
|
164
|
+
let localName = field.localName;
|
|
165
|
+
if (field.oneof) {
|
|
166
|
+
if (jsonValue === null && field.kind == "scalar") {
|
|
167
|
+
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
target = target[field.oneof.localName] = { case: localName };
|
|
171
|
+
localName = "value";
|
|
172
|
+
}
|
|
173
|
+
if (field.repeated) {
|
|
174
|
+
if (jsonValue === null) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (!Array.isArray(jsonValue)) {
|
|
178
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
|
179
|
+
}
|
|
180
|
+
const targetArray = target[localName];
|
|
181
|
+
for (const jsonItem of jsonValue) {
|
|
182
|
+
if (jsonItem === null) {
|
|
183
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`);
|
|
184
|
+
}
|
|
185
|
+
let val;
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- "map" is invalid for repeated fields
|
|
187
|
+
switch (field.kind) {
|
|
188
|
+
case "message":
|
|
189
|
+
val = field.T.fromJson(jsonItem, options);
|
|
190
|
+
break;
|
|
191
|
+
case "enum":
|
|
192
|
+
val = readEnum(field.T, jsonItem, options.ignoreUnknownFields);
|
|
193
|
+
if (val === undefined)
|
|
194
|
+
continue;
|
|
195
|
+
break;
|
|
196
|
+
case "scalar":
|
|
197
|
+
try {
|
|
198
|
+
val = readScalar(field.T, jsonItem, field.L);
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`;
|
|
202
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
203
|
+
m += `: ${e.message}`;
|
|
204
|
+
}
|
|
205
|
+
throw new Error(m);
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
targetArray.push(val);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else if (field.kind == "map") {
|
|
213
|
+
if (jsonValue === null) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (typeof jsonValue != "object" || Array.isArray(jsonValue)) {
|
|
217
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
|
218
|
+
}
|
|
219
|
+
const targetMap = target[localName];
|
|
220
|
+
for (const [jsonMapKey, jsonMapValue] of Object.entries(jsonValue)) {
|
|
221
|
+
if (jsonMapValue === null) {
|
|
222
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: map value null`);
|
|
223
|
+
}
|
|
224
|
+
let val;
|
|
225
|
+
switch (field.V.kind) {
|
|
226
|
+
case "message":
|
|
227
|
+
val = field.V.T.fromJson(jsonMapValue, options);
|
|
228
|
+
break;
|
|
229
|
+
case "enum":
|
|
230
|
+
val = readEnum(field.V.T, jsonMapValue, options.ignoreUnknownFields);
|
|
231
|
+
if (val === undefined)
|
|
232
|
+
continue;
|
|
233
|
+
break;
|
|
234
|
+
case "scalar":
|
|
235
|
+
try {
|
|
236
|
+
val = readScalar(field.V.T, jsonMapValue, LongType.BIGINT);
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
let m = `cannot decode map value for field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
240
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
241
|
+
m += `: ${e.message}`;
|
|
242
|
+
}
|
|
243
|
+
throw new Error(m);
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
targetMap[readScalar(field.K, field.K == ScalarType.BOOL
|
|
249
|
+
? jsonMapKey == "true"
|
|
250
|
+
? true
|
|
251
|
+
: jsonMapKey == "false"
|
|
252
|
+
? false
|
|
253
|
+
: jsonMapKey
|
|
254
|
+
: jsonMapKey, LongType.BIGINT).toString()] = val;
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
let m = `cannot decode map key for field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
258
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
259
|
+
m += `: ${e.message}`;
|
|
260
|
+
}
|
|
261
|
+
throw new Error(m);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
switch (field.kind) {
|
|
267
|
+
case "message":
|
|
268
|
+
const messageType = field.T;
|
|
269
|
+
if (jsonValue === null &&
|
|
270
|
+
messageType.typeName != "google.protobuf.Value") {
|
|
271
|
+
if (field.oneof) {
|
|
272
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: null is invalid for oneof field`);
|
|
273
|
+
}
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (target[localName] instanceof Message) {
|
|
277
|
+
target[localName].fromJson(jsonValue, options);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
target[localName] = messageType.fromJson(jsonValue, options);
|
|
281
|
+
if (messageType.fieldWrapper && !field.oneof) {
|
|
282
|
+
target[localName] = messageType.fieldWrapper.unwrapField(target[localName]);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
case "enum":
|
|
287
|
+
const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields);
|
|
288
|
+
if (enumValue !== undefined) {
|
|
289
|
+
target[localName] = enumValue;
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
case "scalar":
|
|
293
|
+
try {
|
|
294
|
+
target[localName] = readScalar(field.T, jsonValue, field.L);
|
|
295
|
+
}
|
|
296
|
+
catch (e) {
|
|
297
|
+
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
298
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
299
|
+
m += `: ${e.message}`;
|
|
300
|
+
}
|
|
301
|
+
throw new Error(m);
|
|
302
|
+
}
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
262
307
|
// May throw an error. If the error message is non-blank, it should be shown.
|
|
263
308
|
// It is up to the caller to provide context.
|
|
264
309
|
function readScalar(type, json, longType) {
|
|
@@ -270,7 +315,7 @@ function readScalar(type, json, longType) {
|
|
|
270
315
|
case ScalarType.DOUBLE:
|
|
271
316
|
case ScalarType.FLOAT:
|
|
272
317
|
if (json === null)
|
|
273
|
-
return 0.0;
|
|
318
|
+
return 0.0; // TODO field presence: this should reset the field with explicit presence
|
|
274
319
|
if (json === "NaN")
|
|
275
320
|
return Number.NaN;
|
|
276
321
|
if (json === "Infinity")
|
|
@@ -307,7 +352,7 @@ function readScalar(type, json, longType) {
|
|
|
307
352
|
case ScalarType.SINT32:
|
|
308
353
|
case ScalarType.UINT32:
|
|
309
354
|
if (json === null)
|
|
310
|
-
return 0;
|
|
355
|
+
return 0; // TODO field presence: this should reset the field with explicit presence
|
|
311
356
|
let int32;
|
|
312
357
|
if (typeof json == "number")
|
|
313
358
|
int32 = json;
|
|
@@ -327,7 +372,7 @@ function readScalar(type, json, longType) {
|
|
|
327
372
|
case ScalarType.SFIXED64:
|
|
328
373
|
case ScalarType.SINT64:
|
|
329
374
|
if (json === null)
|
|
330
|
-
return protoInt64.zero;
|
|
375
|
+
return protoInt64.zero; // TODO field presence: this should reset the field with explicit presence
|
|
331
376
|
if (typeof json != "number" && typeof json != "string")
|
|
332
377
|
break;
|
|
333
378
|
const long = protoInt64.parse(json);
|
|
@@ -336,7 +381,7 @@ function readScalar(type, json, longType) {
|
|
|
336
381
|
case ScalarType.FIXED64:
|
|
337
382
|
case ScalarType.UINT64:
|
|
338
383
|
if (json === null)
|
|
339
|
-
return protoInt64.zero;
|
|
384
|
+
return protoInt64.zero; // TODO field presence: this should reset the field with explicit presence
|
|
340
385
|
if (typeof json != "number" && typeof json != "string")
|
|
341
386
|
break;
|
|
342
387
|
const uLong = protoInt64.uParse(json);
|
|
@@ -345,14 +390,14 @@ function readScalar(type, json, longType) {
|
|
|
345
390
|
// bool:
|
|
346
391
|
case ScalarType.BOOL:
|
|
347
392
|
if (json === null)
|
|
348
|
-
return false;
|
|
393
|
+
return false; // TODO field presence: this should reset the field with explicit presence
|
|
349
394
|
if (typeof json !== "boolean")
|
|
350
395
|
break;
|
|
351
396
|
return json;
|
|
352
397
|
// string:
|
|
353
398
|
case ScalarType.STRING:
|
|
354
399
|
if (json === null)
|
|
355
|
-
return "";
|
|
400
|
+
return ""; // TODO field presence: this should reset the field with explicit presence
|
|
356
401
|
if (typeof json !== "string") {
|
|
357
402
|
break;
|
|
358
403
|
}
|
|
@@ -369,7 +414,7 @@ function readScalar(type, json, longType) {
|
|
|
369
414
|
// Either standard or URL-safe base64 encoding with/without paddings are accepted.
|
|
370
415
|
case ScalarType.BYTES:
|
|
371
416
|
if (json === null || json === "")
|
|
372
|
-
return new Uint8Array(0);
|
|
417
|
+
return new Uint8Array(0); // TODO field presence: this should reset the field with explicit presence
|
|
373
418
|
if (typeof json !== "string")
|
|
374
419
|
break;
|
|
375
420
|
return protoBase64.dec(json);
|
|
@@ -379,6 +424,7 @@ function readScalar(type, json, longType) {
|
|
|
379
424
|
function readEnum(type, json, ignoreUnknownFields) {
|
|
380
425
|
if (json === null) {
|
|
381
426
|
// proto3 requires 0 to be default value for all enums
|
|
427
|
+
// TODO field presence: this should reset the field with explicit presence
|
|
382
428
|
return 0;
|
|
383
429
|
}
|
|
384
430
|
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2021-
|
|
1
|
+
// Copyright 2021-2024 Buf Technologies, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -16,6 +16,7 @@ import { assert } from "./assert.js";
|
|
|
16
16
|
import { makeJsonFormatCommon } from "./json-format-common.js";
|
|
17
17
|
/* eslint-disable no-case-declarations, @typescript-eslint/restrict-plus-operands,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument */
|
|
18
18
|
export function makeJsonFormatProto2() {
|
|
19
|
+
// TODO field presence: merge this function with proto2
|
|
19
20
|
return makeJsonFormatCommon((writeEnum, writeScalar) => {
|
|
20
21
|
return function writeField(field, value, options) {
|
|
21
22
|
if (field.kind == "map") {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2021-
|
|
1
|
+
// Copyright 2021-2024 Buf Technologies, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -16,6 +16,7 @@ import { assert } from "./assert.js";
|
|
|
16
16
|
import { makeJsonFormatCommon } from "./json-format-common.js";
|
|
17
17
|
/* eslint-disable no-case-declarations, @typescript-eslint/restrict-plus-operands,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument */
|
|
18
18
|
export function makeJsonFormatProto3() {
|
|
19
|
+
// TODO field presence: merge this function with proto2
|
|
19
20
|
return makeJsonFormatCommon((writeEnum, writeScalar) => {
|
|
20
21
|
return function writeField(field, value, options) {
|
|
21
22
|
if (field.kind == "map") {
|
|
@@ -63,7 +64,7 @@ export function makeJsonFormatProto3() {
|
|
|
63
64
|
break;
|
|
64
65
|
case "message":
|
|
65
66
|
for (let i = 0; i < value.length; i++) {
|
|
66
|
-
jsonArr.push(
|
|
67
|
+
jsonArr.push(value[i].toJson(options));
|
|
67
68
|
}
|
|
68
69
|
break;
|
|
69
70
|
}
|
|
@@ -72,15 +73,16 @@ export function makeJsonFormatProto3() {
|
|
|
72
73
|
: undefined;
|
|
73
74
|
}
|
|
74
75
|
else {
|
|
76
|
+
if (value === undefined) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
75
79
|
switch (field.kind) {
|
|
76
80
|
case "scalar":
|
|
77
81
|
return writeScalar(field.T, value, !!field.oneof || field.opt || options.emitDefaultValues);
|
|
78
82
|
case "enum":
|
|
79
83
|
return writeEnum(field.T, value, !!field.oneof || field.opt || options.emitDefaultValues, options.enumAsInteger);
|
|
80
84
|
case "message":
|
|
81
|
-
return value
|
|
82
|
-
? wrapField(field.T, value).toJson(options)
|
|
83
|
-
: undefined;
|
|
85
|
+
return wrapField(field.T, value).toJson(options);
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DescEnum, DescEnumValue, DescField, DescMessage, DescService } from "../descriptor-set.js";
|
|
1
|
+
import type { DescEnum, DescEnumValue, DescExtension, DescField, DescMessage, DescService } from "../descriptor-set.js";
|
|
2
2
|
import type { DescMethod, DescOneof } from "../descriptor-set.js";
|
|
3
3
|
/**
|
|
4
4
|
* Returns the name of a protobuf element in generated code.
|
|
@@ -8,7 +8,7 @@ import type { DescMethod, DescOneof } from "../descriptor-set.js";
|
|
|
8
8
|
* the type name. For nested messages and enumerations, the names are joined
|
|
9
9
|
* with an underscore. For methods, the first character is made lowercase.
|
|
10
10
|
*/
|
|
11
|
-
export declare function localName(desc: DescEnum | DescEnumValue | DescMessage | DescOneof | DescField | DescService | DescMethod): string;
|
|
11
|
+
export declare function localName(desc: DescEnum | DescEnumValue | DescMessage | DescExtension | DescOneof | DescField | DescService | DescMethod): string;
|
|
12
12
|
/**
|
|
13
13
|
* Returns the name of a field in generated code.
|
|
14
14
|
*/
|