function setSchemaNames()

in powershell/plugins/cs-namer-v2.ts [60:168]


function setSchemaNames(schemaGroups: Dictionary<Array<Schema>>, azure: boolean, serviceNamespace: string, keepNames: Array<string>, addAPIVersion = false) {
  const baseNamespace = new Set<string>();
  const subNamespace = new Map<string, Set<string>>();

  // dolauli need to notice this -- schemas in the namespace of the lowest supported api version
  // in Azure Mode, we want to always put schemas into the namespace of the lowest supported apiversion.
  // otherwise, we just want to differentiate with a simple incremental numbering scheme.

  for (const group of values(schemaGroups)) {
    for (const schema of group) {
      if (schema.language.default.skip) {
        continue;
      }
      let thisNamespace = baseNamespace;
      let thisApiversion = '';

      // create the namespace if required
      if (azure) {
        const versions = [...values(schema.apiVersions).select(v => v.version)];
        if (schema.language.default?.uid !== 'universal-parameter-type') {
          if (addAPIVersion && versions && length(versions) > 0) {
            thisApiversion = minimum(versions);
            thisNamespace = subNamespace.get(thisApiversion) || new Set<string>();
            subNamespace.set(thisApiversion, thisNamespace);
          }
        }
      }


      // for each schema, we're going to set the name
      // to the suggested name, unless we have collisions
      // at which point, we're going to add a number (for now?)
      const details = schema.language.default;
      let schemaName = getPascalIdentifier(details.name);
      const apiName = (!thisApiversion) ? '' : getPascalIdentifier(`Api ${thisApiversion}`);
      const ns = addAPIVersion && !!thisApiversion ? ['.', apiName] : [];

      let n = 1;
      while (thisNamespace.has(schemaName) ||
        (keepNames.includes(schemaName) && schema.language.default?.uid !== 'universal-parameter-type')) {
        schemaName = getPascalIdentifier(`${details.name}_${n++}`);
      }
      thisNamespace.add(schemaName);

      // object types.
      if (schema.type === SchemaType.Object || schema.type === SchemaType.Dictionary || schema.type === SchemaType.Any) {
        schema.language.csharp = {
          ...details,
          apiversion: thisApiversion,
          apiname: apiName,
          interfaceName: 'I' + pascalCase(fixLeadingNumber([...deconstruct(schemaName)])), // objects have an interfaceName
          internalInterfaceName: 'I' + pascalCase(fixLeadingNumber([...deconstruct(schemaName), 'Internal'])), // objects have an ineternal interfaceName for setting private members. 
          fullInternalInterfaceName: `${pascalCase([serviceNamespace, '.', 'Models', ...ns])}.${'I' + pascalCase(fixLeadingNumber([...deconstruct(schemaName), 'Internal']))}`,
          name: getPascalIdentifier(schemaName),
          namespace: pascalCase([serviceNamespace, '.', 'Models', ...ns]),  // objects have a namespace
          fullname: `${pascalCase([serviceNamespace, '.', 'Models', ...ns])}.${getPascalIdentifier(schemaName)}`,
        };
      } else if (schema.type === SchemaType.Choice || schema.type === SchemaType.SealedChoice) {
        // oh, it's an enum type
        const choiceSchema = <ChoiceSchema<StringSchema> | SealedChoiceSchema<StringSchema>>schema;
        schema.language.csharp = <SchemaDetails>{
          ...details,
          interfaceName: 'I' + pascalCase(fixLeadingNumber([...deconstruct(schemaName)])),
          name: getPascalIdentifier(schemaName),
          namespace: pascalCase([serviceNamespace, '.', 'Support']),
          fullname: `${pascalCase([serviceNamespace, '.', 'Support'])}.${getPascalIdentifier(schemaName)}`,
          enum: {
            ...schema.language.default.enum,
            name: getPascalIdentifier(schema.language.default.name),
            values: choiceSchema.choices.map(each => {
              return {
                ...each,
                name: getPascalIdentifier(each.language.default.name),
                description: each.language.default.description
              };
            })
          }
        };
      } else {
        schema.language.csharp = <SchemaDetails>{
          ...details,
          interfaceName: '<INVALID_INTERFACE>',
          internalInterfaceName: '<INVALID_INTERFACE>',
          name: schemaName,
          namespace: '<INVALID_NAMESPACE>',
          fullname: '<INVALID_FULLNAME>'
        };
        // xichen: for invalid namespace case, we won't create model class. So we do not need consider dup case
        thisNamespace.delete(schemaName);
      }

      // name each property in this schema
      setPropertyNames(schema);

      // fix enum names
      if (schema.type === SchemaType.Choice || schema.type === SchemaType.SealedChoice) {
        schema.language.csharp.enum.name = getPascalIdentifier(schema.language.default.name);

        // and the value names themselves
        for (const value of values(schema.language.csharp.enum.values)) {
          // In m3, enum.name and enum.value are same. But in m4, enum.name is named by m4.
          // To keep same action as m3, use enum.value here
          (<any>value).name = getPascalIdentifier((<any>value).value);
        }
      }
    }
  }

}