Skip to content

Commit 462132f

Browse files
gideongoodwindcodeIO
authored andcommitted
New: Preserve comments when serializing/deserializing with toJSON and fromJSON. (#983)
1 parent 635fef0 commit 462132f

13 files changed

+249
-50
lines changed

index.d.ts

+51-14
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,20 @@ export class Enum extends ReflectionObject {
156156
* @param name Unique name within its namespace
157157
* @param [values] Enum values as an object, by name
158158
* @param [options] Declared options
159+
* @param [comment] The comment for this enum
160+
* @param [comments] The value comments for this enum
159161
*/
160-
constructor(name: string, values?: { [k: string]: number }, options?: { [k: string]: any });
162+
constructor(name: string, values?: { [k: string]: number }, options?: { [k: string]: any }, comment?: string, comments?: { [k: string]: string });
161163

162164
/** Enum values by id. */
163165
public valuesById: { [k: number]: string };
164166

165167
/** Enum values by name. */
166168
public values: { [k: string]: number };
167169

170+
/** Enum comment text. */
171+
public comment: (string|null);
172+
168173
/** Value comment texts, if any. */
169174
public comments: { [k: string]: string };
170175

@@ -182,9 +187,10 @@ export class Enum extends ReflectionObject {
182187

183188
/**
184189
* Converts this enum to an enum descriptor.
190+
* @param [toJSONOptions] JSON conversion options
185191
* @returns Enum descriptor
186192
*/
187-
public toJSON(): IEnum;
193+
public toJSON(toJSONOptions?: IToJSONOptions): IEnum;
188194

189195
/**
190196
* Adds a value to this enum.
@@ -288,8 +294,9 @@ export class FieldBase extends ReflectionObject {
288294
* @param [rule="optional"] Field rule
289295
* @param [extend] Extended type if different from parent
290296
* @param [options] Declared options
297+
* @param [comment] Comment associated with this field
291298
*/
292-
constructor(name: string, id: number, type: string, rule?: (string|{ [k: string]: any }), extend?: (string|{ [k: string]: any }), options?: { [k: string]: any });
299+
constructor(name: string, id: number, type: string, rule?: (string|{ [k: string]: any }), extend?: (string|{ [k: string]: any }), options?: { [k: string]: any }, comment?: string);
293300

294301
/** Field rule, if any. */
295302
public rule?: string;
@@ -342,11 +349,15 @@ export class FieldBase extends ReflectionObject {
342349
/** Sister-field within the declaring namespace if an extended field. */
343350
public declaringField: (Field|null);
344351

352+
/** Comment for this field. */
353+
public comment: (string|null);
354+
345355
/**
346356
* Converts this field to a field descriptor.
357+
* @param [toJSONOptions] JSON conversion options
347358
* @returns Field descriptor
348359
*/
349-
public toJSON(): IField;
360+
public toJSON(toJSONOptions?: IToJSONOptions): IField;
350361

351362
/**
352363
* Resolves this field's type references.
@@ -445,8 +456,9 @@ export class MapField extends FieldBase {
445456
* @param keyType Key type
446457
* @param type Value type
447458
* @param [options] Declared options
459+
* @param [comment] Comment associated with this field
448460
*/
449-
constructor(name: string, id: number, keyType: string, type: string, options?: { [k: string]: any });
461+
constructor(name: string, id: number, keyType: string, type: string, options?: { [k: string]: any }, comment?: string);
450462

451463
/** Key type. */
452464
public keyType: string;
@@ -465,9 +477,10 @@ export class MapField extends FieldBase {
465477

466478
/**
467479
* Converts this map field to a map field descriptor.
480+
* @param [toJSONOptions] JSON conversion options
468481
* @returns Map field descriptor
469482
*/
470-
public toJSON(): IMapField;
483+
public toJSON(toJSONOptions?: IToJSONOptions): IMapField;
471484

472485
/**
473486
* Map field decorator (TypeScript).
@@ -586,8 +599,9 @@ export class Method extends ReflectionObject {
586599
* @param [requestStream] Whether the request is streamed
587600
* @param [responseStream] Whether the response is streamed
588601
* @param [options] Declared options
602+
* @param [comment] The comment for this method
589603
*/
590-
constructor(name: string, type: (string|undefined), requestType: string, responseType: string, requestStream?: (boolean|{ [k: string]: any }), responseStream?: (boolean|{ [k: string]: any }), options?: { [k: string]: any });
604+
constructor(name: string, type: (string|undefined), requestType: string, responseType: string, requestStream?: (boolean|{ [k: string]: any }), responseStream?: (boolean|{ [k: string]: any }), options?: { [k: string]: any }, comment?: string);
591605

592606
/** Method type. */
593607
public type: string;
@@ -610,6 +624,9 @@ export class Method extends ReflectionObject {
610624
/** Resolved response type. */
611625
public resolvedResponseType: (Type|null);
612626

627+
/** Comment for this method */
628+
public comment: (string|null);
629+
613630
/**
614631
* Constructs a method from a method descriptor.
615632
* @param name Method name
@@ -621,9 +638,10 @@ export class Method extends ReflectionObject {
621638

622639
/**
623640
* Converts this method to a method descriptor.
641+
* @param [toJSONOptions] JSON conversion options
624642
* @returns Method descriptor
625643
*/
626-
public toJSON(): IMethod;
644+
public toJSON(toJSONOptions?: IToJSONOptions): IMethod;
627645
}
628646

629647
/** Method descriptor. */
@@ -670,9 +688,10 @@ export class Namespace extends NamespaceBase {
670688
/**
671689
* Converts an array of reflection objects to JSON.
672690
* @param array Object array
691+
* @param [toJSONOptions] JSON conversion options
673692
* @returns JSON object or `undefined` when array is empty
674693
*/
675-
public static arrayToJSON(array: ReflectionObject[]): ({ [k: string]: any }|undefined);
694+
public static arrayToJSON(array: ReflectionObject[], toJSONOptions?: IToJSONOptions): ({ [k: string]: any }|undefined);
676695

677696
/**
678697
* Tests if the specified id is reserved.
@@ -702,9 +721,10 @@ export abstract class NamespaceBase extends ReflectionObject {
702721

703722
/**
704723
* Converts this namespace to a namespace descriptor.
724+
* @param [toJSONOptions] JSON conversion options
705725
* @returns Namespace descriptor
706726
*/
707-
public toJSON(): INamespace;
727+
public toJSON(toJSONOptions?: IToJSONOptions): INamespace;
708728

709729
/**
710730
* Adds nested objects to this namespace from nested object descriptors.
@@ -921,15 +941,19 @@ export class OneOf extends ReflectionObject {
921941
* @param name Oneof name
922942
* @param [fieldNames] Field names
923943
* @param [options] Declared options
944+
* @param [comment] Comment associated with this field
924945
*/
925-
constructor(name: string, fieldNames?: (string[]|{ [k: string]: any }), options?: { [k: string]: any });
946+
constructor(name: string, fieldNames?: (string[]|{ [k: string]: any }), options?: { [k: string]: any }, comment?: string);
926947

927948
/** Field names that belong to this oneof. */
928949
public oneof: string[];
929950

930951
/** Fields that belong to this oneof as an array for iteration. */
931952
public readonly fieldsArray: Field[];
932953

954+
/** Comment for this field. */
955+
public comment: (string|null);
956+
933957
/**
934958
* Constructs a oneof from a oneof descriptor.
935959
* @param name Oneof name
@@ -941,9 +965,10 @@ export class OneOf extends ReflectionObject {
941965

942966
/**
943967
* Converts this oneof to a oneof descriptor.
968+
* @param [toJSONOptions] JSON conversion options
944969
* @returns Oneof descriptor
945970
*/
946-
public toJSON(): IOneOf;
971+
public toJSON(toJSONOptions?: IToJSONOptions): IOneOf;
947972

948973
/**
949974
* Adds a field to this oneof and removes it from its current parent, if any.
@@ -1016,6 +1041,16 @@ export interface IParseOptions {
10161041

10171042
/** Keeps field casing instead of converting to camel case */
10181043
keepCase?: boolean;
1044+
1045+
/** Recognize double-slash comments in addition to doc-block comments. */
1046+
alternateCommentMode?: boolean;
1047+
}
1048+
1049+
/** Options modifying the behavior of JSON serialization. */
1050+
export interface IToJSONOptions {
1051+
1052+
/** Serializes comments. */
1053+
keepComments?: boolean;
10191054
}
10201055

10211056
/**
@@ -1345,9 +1380,10 @@ export class Service extends NamespaceBase {
13451380

13461381
/**
13471382
* Converts this service to a service descriptor.
1383+
* @param [toJSONOptions] JSON conversion options
13481384
* @returns Service descriptor
13491385
*/
1350-
public toJSON(): IService;
1386+
public toJSON(toJSONOptions?: IToJSONOptions): IService;
13511387

13521388
/** Methods of this service as an array for iteration. */
13531389
public readonly methodsArray: Method[];
@@ -1497,9 +1533,10 @@ export class Type extends NamespaceBase {
14971533

14981534
/**
14991535
* Converts this message type to a message type descriptor.
1536+
* @param [toJSONOptions] JSON conversion options
15001537
* @returns Message type descriptor
15011538
*/
1502-
public toJSON(): IType;
1539+
public toJSON(toJSONOptions?: IToJSONOptions): IType;
15031540

15041541
/**
15051542
* Adds a nested object to this type.

src/enum.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ var Namespace = require("./namespace"),
1616
* @param {string} name Unique name within its namespace
1717
* @param {Object.<string,number>} [values] Enum values as an object, by name
1818
* @param {Object.<string,*>} [options] Declared options
19+
* @param {string} [comment] The comment for this enum
20+
* @param {Object.<string,string>} [comments] The value comments for this enum
1921
*/
20-
function Enum(name, values, options) {
22+
function Enum(name, values, options, comment, comments) {
2123
ReflectionObject.call(this, name, options);
2224

2325
if (values && typeof values !== "object")
@@ -35,11 +37,17 @@ function Enum(name, values, options) {
3537
*/
3638
this.values = Object.create(this.valuesById); // toJSON, marker
3739

40+
/**
41+
* Enum comment text.
42+
* @type {string|null}
43+
*/
44+
this.comment = comment;
45+
3846
/**
3947
* Value comment texts, if any.
4048
* @type {Object.<string,string>}
4149
*/
42-
this.comments = {};
50+
this.comments = comments || {};
4351

4452
/**
4553
* Reserved ranges, if any.
@@ -72,20 +80,24 @@ function Enum(name, values, options) {
7280
* @throws {TypeError} If arguments are invalid
7381
*/
7482
Enum.fromJSON = function fromJSON(name, json) {
75-
var enm = new Enum(name, json.values, json.options);
83+
var enm = new Enum(name, json.values, json.options, json.comment, json.comments);
7684
enm.reserved = json.reserved;
7785
return enm;
7886
};
7987

8088
/**
8189
* Converts this enum to an enum descriptor.
90+
* @param {IToJSONOptions} [toJSONOptions] JSON conversion options
8291
* @returns {IEnum} Enum descriptor
8392
*/
84-
Enum.prototype.toJSON = function toJSON() {
93+
Enum.prototype.toJSON = function toJSON(toJSONOptions) {
94+
var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
8595
return util.toObject([
8696
"options" , this.options,
8797
"values" , this.values,
88-
"reserved" , this.reserved && this.reserved.length ? this.reserved : undefined
98+
"reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
99+
"comment" , keepComments ? this.comment : undefined,
100+
"comments" , keepComments ? this.comments : undefined
89101
]);
90102
};
91103

src/field.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ var ruleRe = /^required|optional|repeated$/;
3535
* @throws {TypeError} If arguments are invalid
3636
*/
3737
Field.fromJSON = function fromJSON(name, json) {
38-
return new Field(name, json.id, json.type, json.rule, json.extend, json.options);
38+
return new Field(name, json.id, json.type, json.rule, json.extend, json.options, json.comment);
3939
};
4040

4141
/**
@@ -50,13 +50,16 @@ Field.fromJSON = function fromJSON(name, json) {
5050
* @param {string|Object.<string,*>} [rule="optional"] Field rule
5151
* @param {string|Object.<string,*>} [extend] Extended type if different from parent
5252
* @param {Object.<string,*>} [options] Declared options
53+
* @param {string} [comment] Comment associated with this field
5354
*/
54-
function Field(name, id, type, rule, extend, options) {
55+
function Field(name, id, type, rule, extend, options, comment) {
5556

5657
if (util.isObject(rule)) {
58+
comment = extend;
5759
options = rule;
5860
rule = extend = undefined;
5961
} else if (util.isObject(extend)) {
62+
comment = options;
6063
options = extend;
6164
extend = undefined;
6265
}
@@ -183,6 +186,12 @@ function Field(name, id, type, rule, extend, options) {
183186
* @private
184187
*/
185188
this._packed = null;
189+
190+
/**
191+
* Comment for this field.
192+
* @type {string|null}
193+
*/
194+
this.comment = comment;
186195
}
187196

188197
/**
@@ -227,15 +236,18 @@ Field.prototype.setOption = function setOption(name, value, ifNotSet) {
227236

228237
/**
229238
* Converts this field to a field descriptor.
239+
* @param {IToJSONOptions} [toJSONOptions] JSON conversion options
230240
* @returns {IField} Field descriptor
231241
*/
232-
Field.prototype.toJSON = function toJSON() {
242+
Field.prototype.toJSON = function toJSON(toJSONOptions) {
243+
var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
233244
return util.toObject([
234245
"rule" , this.rule !== "optional" && this.rule || undefined,
235246
"type" , this.type,
236247
"id" , this.id,
237248
"extend" , this.extend,
238-
"options" , this.options
249+
"options" , this.options,
250+
"comment" , keepComments ? this.comment : undefined
239251
]);
240252
};
241253

src/mapfield.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ var types = require("./types"),
1818
* @param {string} keyType Key type
1919
* @param {string} type Value type
2020
* @param {Object.<string,*>} [options] Declared options
21+
* @param {string} [comment] Comment associated with this field
2122
*/
22-
function MapField(name, id, keyType, type, options) {
23-
Field.call(this, name, id, type, options);
23+
function MapField(name, id, keyType, type, options, comment) {
24+
Field.call(this, name, id, type, undefined, undefined, options, comment);
2425

2526
/* istanbul ignore if */
2627
if (!util.isString(keyType))
@@ -64,20 +65,23 @@ function MapField(name, id, keyType, type, options) {
6465
* @throws {TypeError} If arguments are invalid
6566
*/
6667
MapField.fromJSON = function fromJSON(name, json) {
67-
return new MapField(name, json.id, json.keyType, json.type, json.options);
68+
return new MapField(name, json.id, json.keyType, json.type, json.options, json.comment);
6869
};
6970

7071
/**
7172
* Converts this map field to a map field descriptor.
73+
* @param {IToJSONOptions} [toJSONOptions] JSON conversion options
7274
* @returns {IMapField} Map field descriptor
7375
*/
74-
MapField.prototype.toJSON = function toJSON() {
76+
MapField.prototype.toJSON = function toJSON(toJSONOptions) {
77+
var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
7578
return util.toObject([
7679
"keyType" , this.keyType,
7780
"type" , this.type,
7881
"id" , this.id,
7982
"extend" , this.extend,
80-
"options" , this.options
83+
"options" , this.options,
84+
"comment" , keepComments ? this.comment : undefined
8185
]);
8286
};
8387

0 commit comments

Comments
 (0)