constructor()

in powershell/llcsharp/model/model-class-json.ts [42:179]


  constructor(protected modelClass: ModelClass, objectInitializer?: DeepPartial<JsonSerializableClass>) {
    super(modelClass.namespace, modelClass.name);
    this.apply(objectInitializer);
    this.partial = true;
    this.description = modelClass.description;
    this.addPartialMethods();

    // set up the declaration for the toJson method.
    const container = new Parameter('container', ClientRuntime.JsonObject, { description: `The <see cref="${ClientRuntime.JsonObject}"/> container to serialize this object into. If the caller passes in <c>null</c>, a new instance will be created and returned to the caller.` });
    const mode = new Parameter('serializationMode', ClientRuntime.SerializationMode, { description: `Allows the caller to choose the depth of the serialization. See <see cref="${ClientRuntime.SerializationMode}"/>.` });

    const toJsonMethod = this.addMethod(new Method('ToJson', ClientRuntime.JsonNode, {
      parameters: [container, mode],
      description: `Serializes this instance of <see cref="${this.name}" /> into a <see cref="${ClientRuntime.JsonNode}" />.`,
      returnsDescription: `a serialized instance of <see cref="${this.name}" /> as a <see cref="${ClientRuntime.JsonNode}" />.`
    }));

    // setup the declaration for the json deserializer constructor
    const jsonParameter = new Parameter('json', ClientRuntime.JsonObject, { description: `A ${ClientRuntime.JsonObject} instance to deserialize from.` });
    const deserializerConstructor = this.addMethod(new Constructor(this, {
      parameters: [jsonParameter], access: Access.Internal,
      description: `Deserializes a ${ClientRuntime.JsonObject} into a new instance of <see cref="${this.name}" />.`
    }));


    const serializeStatements = new Statements();
    const deserializeStatements = new Statements();
    this.excludes = '';

    if (this.modelClass.dictionaryImpl) {
      const vType = this.modelClass.dictionaryImpl.valueType;
      // we have to ensure that all the known wire-names are excluded on deserialization.
      const exclusions = new Parameter('exclusions', System.Collections.Generic.HashSet(dotnet.String), { defaultInitializer: dotnet.Null });
      deserializerConstructor.parameters.push(exclusions);

      this.excludes = [...values(newGetAllProperties(<ObjectSchema>this.modelClass.schema)).select(each => each.serializedName).select(each => new StringExpression(each))].join();
      this.excludes = this.excludes ? `,${System.Collections.Generic.HashSet(dotnet.String).new()}{ ${this.excludes} }` : '';

      const ap = `((${ClientRuntime}.IAssociativeArray<${vType.declaration}>)this).AdditionalProperties`;

      if (this.modelClass.dictionaryImpl.ownsDictionary) {
        // we have to implement the deserializer for it.

        serializeStatements.push(new Statements(`${ClientRuntime.JsonSerializable}.ToJson( ${ap}, ${container});`));

        if (vType === System.Object) {
          // wildcard style
          deserializeStatements.push(new Statements(`${ClientRuntime.JsonSerializable}.FromJson( json, ${ap}, ${ClientRuntime.JsonSerializable}.DeserializeDictionary(()=>${System.Collections.Generic.Dictionary(System.String, System.Object).new()}),${exclusions.value} );`));

        } else if (vType instanceof ModelInterface) {
          // use the class of the dictionary value to deserialize values
          deserializeStatements.push(new Statements(`${ClientRuntime.JsonSerializable}.FromJson( json, ${ap}, (j) => ${vType.classImplementation.fullName}.FromJson(j) ,${exclusions.value} );`));
        } else {
          deserializeStatements.push(new Statements(`${ClientRuntime.JsonSerializable}.FromJson( json, ${ap}, null ,${exclusions.value} );`));
        }
      }
    }


    for (const each of values(modelClass.backingFields)) {
      serializeStatements.add(`${each.field.value}?.ToJson(${container}, ${mode.use});`);
      const sch = (<EnhancedTypeDeclaration>each.typeDeclaration).schema;
      const dictSchema = sch.type === SchemaType.Dictionary ? sch :
        sch.type === SchemaType.Object ? (<ObjectSchema>sch).parents?.immediate.find((s) => s.type === SchemaType.Dictionary) :
          undefined;
      if (dictSchema) {
        deserializeStatements.add(`${each.field.value} = new ${each.className}(json${this.excludes});`);
      } else {
        deserializeStatements.add(`${each.field.value} = new ${each.className}(json);`);
      }
    }

    pushTempVar();
    for (const prop of values(modelClass.ownedProperties)) {
      if (prop.language.csharp.HeaderProperty === 'Header') {
        continue;
      }
      const serializeStatement = (<EnhancedTypeDeclaration>prop.type).serializeToContainerMember(KnownMediaType.Json, prop.valuePrivate, container, prop.serializedName, mode);

      if (!prop.language.csharp.read && !prop.language.csharp.create && !prop.language.csharp.update) {
        continue;
      } else if (!(prop.language.csharp.read && prop.language.csharp.create && prop.language.csharp.update)) {
        const accessControlArray = new Array<string>();
        if (prop.language.csharp.read) {
          accessControlArray.push(ClientRuntime.SerializationMode.IncludeRead.toString());
        }
        if (prop.language.csharp.update) {
          accessControlArray.push(ClientRuntime.SerializationMode.IncludeUpdate.toString());
        }
        if (prop.language.csharp.create) {
          accessControlArray.push(ClientRuntime.SerializationMode.IncludeCreate.toString());
        }
        if (accessControlArray.length > 0) {
          for (let i = 0; i < accessControlArray.length; i++) {
            accessControlArray[i] = `${mode.use}.HasFlag(${accessControlArray[i]})`;
          }
          const accessControl = accessControlArray.join('||');
          serializeStatements.add(If(accessControl, serializeStatement));
        }
      } else {
        serializeStatements.add(serializeStatement);
      }

      if (prop.language.csharp.read) {
        deserializeStatements.add(prop.assignPrivate((<EnhancedTypeDeclaration>prop.type).deserializeFromContainerMember(KnownMediaType.Json, jsonParameter, prop.serializedName, new LiteralExpression(prop.backingName))));
      }
    }
    popTempVar();

    const $this = this;

    // generate the implementation for toJson
    toJsonMethod.add(function* () {
      yield `${container} = ${container} ?? new ${ClientRuntime.JsonObject.declaration}();`;
      yield EOL;

      yield 'bool returnNow = false;';
      yield `${$this.btj.name}(ref ${container}, ref returnNow);`;

      yield If(toExpression('returnNow'), `return ${container};`);

      // get serialization statements
      yield serializeStatements;

      yield `${$this.atj.name}(ref ${container});`;
      yield 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(toExpression('returnNow'), 'return;');

      yield deserializeStatements;
      yield `${$this.afj.name}(json);`;
    });
  }