@microsoft.azure/autorest.incubator
Version:
AutoRest incubator project
152 lines • 9.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dictionary_1 = require("../../../common/dictionary");
const text_manipulation_1 = require("../../../common/text-manipulation");
const access_modifier_1 = require("../../../csharp/code-dom/access-modifier");
const class_1 = require("../../../csharp/code-dom/class");
const constructor_1 = require("../../../csharp/code-dom/constructor");
const expression_1 = require("../../../csharp/code-dom/expression");
const method_1 = require("../../../csharp/code-dom/method");
const dotnet = require("../../../csharp/code-dom/mscorlib");
const parameter_1 = require("../../../csharp/code-dom/parameter");
const parameter_modifier_1 = require("../../../csharp/code-dom/parameter-modifier");
const case_1 = require("../../../csharp/code-dom/statements/case");
const if_1 = require("../../../csharp/code-dom/statements/if");
const return_1 = require("../../../csharp/code-dom/statements/return");
const statement_1 = require("../../../csharp/code-dom/statements/statement");
const switch_1 = require("../../../csharp/code-dom/statements/switch");
const ternery_1 = require("../../../csharp/code-dom/ternery");
const clientruntime_1 = require("../../../csharp/lowlevel-generator/clientruntime");
const tweak_model_1 = require("../../../remodeler/tweak-model");
const media_types_1 = require("../../../common/media-types");
const primitive_1 = require("../../../csharp/schema/primitive");
class JsonSerializableClass extends class_1.Class {
constructor(modelClass, objectInitializer) {
super(modelClass.namespace, modelClass.name);
this.modelClass = modelClass;
this.apply(objectInitializer);
this.partial = true;
this.addPartialMethods();
// set up the declaration for the toJson method.
const container = new parameter_1.Parameter('container', clientruntime_1.ClientRuntime.JsonObject);
const mode = new parameter_1.Parameter('serializationMode', clientruntime_1.ClientRuntime.SerializationMode);
const toJsonMethod = this.addMethod(new method_1.Method('ToJson', clientruntime_1.ClientRuntime.JsonNode, {
parameters: [container, mode],
}));
// setup the declaration for the json deserializer constructor
const jsonParameter = new parameter_1.Parameter('json', clientruntime_1.ClientRuntime.JsonObject);
const deserializerConstructor = this.addMethod(new constructor_1.Constructor(this, { parameters: [jsonParameter], access: access_modifier_1.Access.Internal }));
const serializeStatements = new statement_1.Statements();
const deserializeStatements = new statement_1.Statements();
for (const each of dictionary_1.values(modelClass.backingFields)) {
serializeStatements.add(`${each.field.value}?.ToJson(result, ${mode.use});`);
deserializeStatements.add(`${each.field.value} = new ${each.className}(json);`);
}
primitive_1.pushTempVar();
for (const { key: propertyName, value: property } of dictionary_1.items(modelClass.schema.properties)) {
const prop = modelClass.$(property.details.csharp.name);
const serializeStatement = prop.type.serializeToContainerMember(media_types_1.KnownMediaType.Json, prop, container, prop.serializedName);
if (property.details.csharp[tweak_model_1.HeaderProperty] === tweak_model_1.HeaderPropertyType.Header) {
// it's a header only property. Don't serialize unless the mode has Microsoft.Rest.ClientRuntime.SerializationMode.IncludeHeaders enabled
serializeStatements.add(if_1.If({ value: `${mode.use}.HasFlag(Microsoft.Rest.ClientRuntime.SerializationMode.IncludeHeaders)` }, serializeStatement));
}
else {
if (property.schema.readOnly) {
serializeStatements.add(if_1.If({ value: `${mode.use}.HasFlag(Microsoft.Rest.ClientRuntime.SerializationMode.IncludeReadOnly)` }, serializeStatement));
}
else {
serializeStatements.add(serializeStatement);
}
}
deserializeStatements.add(prop.assignPrivate(prop.type.deserializeFromContainerMember(media_types_1.KnownMediaType.Json, jsonParameter, prop.serializedName, prop)));
}
primitive_1.popTempVar();
const $this = this;
// generate the implementation for toJson
toJsonMethod.add(function* () {
yield `${container} = ${container} ?? new ${clientruntime_1.ClientRuntime.JsonObject.declaration}();`;
yield text_manipulation_1.EOL;
yield `bool returnNow = false;`;
yield `${$this.btj.name}(ref ${container}, ref returnNow);`;
yield if_1.If({ value: `returnNow` }, `return ${container};`);
// get serialization statements
yield serializeStatements;
yield `${$this.atj.name}(ref ${container});`;
yield return_1.Return(container);
});
// and let's fill in the deserializer constructor statements now.
deserializerConstructor.add(function* () {
yield `bool returnNow = false;`;
yield `${$this.bfj.name}(json, ref returnNow);`;
yield if_1.If({ value: `returnNow` }, `return;`);
yield deserializeStatements;
yield `${$this.afj.name}(json);`;
});
}
get definition() {
const $this = this.modelClass;
// gotta write this just before we write out the class, since we had to wait until everyone had reported to their parents.
const d = this.modelClass.discriminators;
const isp = this.modelClass.isPolymorphic;
// create the FromJson method
const node = new parameter_1.Parameter('node', clientruntime_1.ClientRuntime.JsonNode);
const fromJson = this.addMethod(new method_1.Method('FromJson', this.modelClass.modelInterface, { parameters: [node], static: access_modifier_1.Modifier.Static }));
fromJson.add(function* () {
const json = expression_1.IsDeclaration(node, clientruntime_1.ClientRuntime.JsonObject, 'json');
if (isp) {
yield if_1.If(if_1.Not(json.check), return_1.Return(dotnet.Null));
yield '// Polymorphic type -- select the appropriate constructor using the discriminator';
/** go thru the list of polymorphic values for the discriminator, and call the target class's constructor for that */
if ($this.schema.discriminator) {
yield switch_1.Switch({ value: `json.StringProperty("${$this.schema.discriminator.propertyName}")` }, function* () {
for (const { key, value } of dictionary_1.items(d)) {
yield case_1.TerminalCase(`"${key}"`, function* () {
yield return_1.Return(value.newInstance(json));
});
}
});
}
yield return_1.Return($this.newInstance(json));
}
else {
// just tell it to create the instance (providing that it's a JSonObject)
yield return_1.Return(ternery_1.Ternery(json.check, $this.newInstance(json), dotnet.Null));
}
});
return super.definition;
}
get fileName() {
return `${super.fileName}.json`;
}
addPartialMethods() {
// add partial methods for future customization
this.btj = this.addMethod(new method_1.PartialMethod('BeforeToJson', dotnet.Void, {
access: access_modifier_1.Access.Default,
parameters: [
new parameter_1.Parameter('container', clientruntime_1.ClientRuntime.JsonObject, { modifier: parameter_modifier_1.ParameterModifier.Ref, description: 'The JSON container that the serialization result will be placed in.' }),
new parameter_1.Parameter('returnNow', dotnet.Bool, { modifier: parameter_modifier_1.ParameterModifier.Ref, description: 'Determines if the rest of the serialization should be processed, or if the method should return instantly.' }),
],
}));
this.atj = this.addMethod(new method_1.PartialMethod('AfterToJson', dotnet.Void, {
access: access_modifier_1.Access.Default,
parameters: [
new parameter_1.Parameter('container', clientruntime_1.ClientRuntime.JsonObject, { modifier: parameter_modifier_1.ParameterModifier.Ref, description: 'The JSON container that the serialization result will be placed in.' }),
],
}));
this.bfj = this.addMethod(new method_1.PartialMethod('BeforeFromJson', dotnet.Void, {
access: access_modifier_1.Access.Default,
parameters: [
new parameter_1.Parameter('json', clientruntime_1.ClientRuntime.JsonObject, { description: 'The JsonNode that should be deserialized into this object.' }),
new parameter_1.Parameter('returnNow', dotnet.Bool, { modifier: parameter_modifier_1.ParameterModifier.Ref, description: 'Determines if the rest of the deserialization should be processed, or if the method should return instantly.' }),
],
}));
this.afj = this.addMethod(new method_1.PartialMethod('AfterFromJson', dotnet.Void, {
access: access_modifier_1.Access.Default,
parameters: [
new parameter_1.Parameter('json', clientruntime_1.ClientRuntime.JsonObject, { description: 'The JsonNode that should be deserialized into this object.' }),
],
}));
}
}
exports.JsonSerializableClass = JsonSerializableClass;
//# sourceMappingURL=model-class-json.js.map