function generateJSONUnmarshallerBody()

in packages/codegen.go/src/models.ts [424:530]


function generateJSONUnmarshallerBody(modelType: go.ModelType | go.PolymorphicType, modelDef: ModelDef, receiver: string, imports: ImportManager, options: go.Options): string {
  const emitAddlProps = function (tab: string, addlProps: go.MapType): string {
    let addlPropsText = `${tab}\t\tif ${receiver}.AdditionalProperties == nil {\n`;
    let ref = '';
    if (!addlProps.valueTypeByValue) {
      ref = '&';
    }
    addlPropsText += `${tab}\t\t\t${receiver}.AdditionalProperties = ${go.getTypeDeclaration(addlProps)}{}\n`;
    addlPropsText += `${tab}\t\t}\n`;
    addlPropsText += `${tab}\t\tif val != nil {\n`;
    let auxType = go.getTypeDeclaration(addlProps.valueType);
    let assignment = `${ref}aux`;
    if (go.isTimeType(addlProps.valueType)) {
      imports.add('time');
      auxType = addlProps.valueType.dateTimeFormat!;
      assignment = `(*time.Time)(${assignment})`;
    }
    addlPropsText += `${tab}\t\t\tvar aux ${auxType}\n`;
    addlPropsText += `${tab}\t\t\terr = json.Unmarshal(val, &aux)\n`;
    addlPropsText += `${tab}\t\t\t${receiver}.AdditionalProperties[key] = ${assignment}\n`;
    addlPropsText += `${tab}\t\t}\n`;
    addlPropsText += `${tab}\t\tdelete(rawMsg, key)\n`;
    return addlPropsText;
  };
  let unmarshalBody = '';
  unmarshalBody = '\tfor key, val := range rawMsg {\n';
  unmarshalBody += '\t\tvar err error\n';
  unmarshalBody += '\t\tswitch key {\n';
  let addlProps: go.MapType | undefined;
  for (const field of values(modelType.fields)) {
    if (go.isMapType(field.type) && field.annotations.isAdditionalProperties) {
      addlProps = field.type;
      continue;
    }
    unmarshalBody += `\t\tcase "${field.serializedName}":\n`;
    if (hasDiscriminatorInterface(field.type)) {
      unmarshalBody += generateDiscriminatorUnmarshaller(field, receiver);
    } else if (go.isTimeType(field.type)) {
      unmarshalBody += `\t\t\t\terr = unpopulate${capitalize(field.type.dateTimeFormat)}(val, "${field.name}", &${receiver}.${field.name})\n`;
      modelDef.SerDe.needsJSONUnpopulate = true;
    } else if (go.isSliceType(field.type) && go.isTimeType(field.type.elementType)) {
      imports.add('time');
      let elementPtr = '*';
      if (field.type.elementTypeByValue) {
        elementPtr = '';
      }
      unmarshalBody += `\t\t\tvar aux []${elementPtr}${field.type.elementType.dateTimeFormat}\n`;
      unmarshalBody += `\t\t\terr = unpopulate(val, "${field.name}", &aux)\n`;
      unmarshalBody += '\t\t\tfor _, au := range aux {\n';
      unmarshalBody += `\t\t\t\t${receiver}.${field.name} = append(${receiver}.${field.name}, (${elementPtr}time.Time)(au))\n`;
      unmarshalBody += '\t\t\t}\n';
      modelDef.SerDe.needsJSONUnpopulate = true;
    } else if (go.isBytesType(field.type)) {
      imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
      unmarshalBody += '\t\tif val != nil && string(val) != "null" {\n';
      unmarshalBody += `\t\t\t\terr = runtime.DecodeByteArray(string(val), &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n\t\t}\n`;
    } else if (go.isSliceType(field.type) && go.isBytesType(field.type.elementType)) {
      imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
      unmarshalBody += '\t\t\tvar encodedValue []string\n';
      unmarshalBody += `\t\t\terr = unpopulate(val, "${field.name}", &encodedValue)\n`;
      unmarshalBody += '\t\t\tif err == nil && len(encodedValue) > 0 {\n';
      unmarshalBody += `\t\t\t\t${receiver}.${field.name} = make([][]byte, len(encodedValue))\n`;
      unmarshalBody += '\t\t\t\tfor i := 0; i < len(encodedValue) && err == nil; i++ {\n';
      unmarshalBody += `\t\t\t\t\terr = runtime.DecodeByteArray(encodedValue[i], &${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n`;
      unmarshalBody += '\t\t\t\t}\n\t\t\t}\n';
      modelDef.SerDe.needsJSONUnpopulate = true;
    } else if (go.isSliceType(field.type) && field.type.rawJSONAsBytes) {
      unmarshalBody += '\t\t\tif string(val) != "null" {\n';
      unmarshalBody += `\t\t\t\t${receiver}.${field.name} = val\n\t\t\t}\n`;
    } else if (go.isPrimitiveType(field.type) && (field.type.typeName.startsWith('uint') || field.type.typeName.startsWith('int')) && field.type.encodeAsString) {
      // TODO: need to handle map and slice type with underlying int as string type
      imports.add('strconv');
      unmarshalBody += `\t\t\t\tvar aux string\n`;
      unmarshalBody += `\t\t\t\terr = unpopulate(val, "${field.name}", &aux)\n`;
      unmarshalBody += `\t\t\t\tif err == nil {\n`;
      unmarshalBody += `\t\t\t\t\tvar v ${field.type.typeName.startsWith('int') ? 'int64' : 'uint64'}\n`;
      unmarshalBody += `\t\t\t\t\tv, err = strconv.${field.type.typeName.startsWith('int') ? 'ParseInt' : 'ParseUint'}(aux, 10, 0)\n`;
      unmarshalBody += `\t\t\t\t\tif err == nil {\n`;
      if (field.type.typeName.startsWith('uint') && field.type.typeName !== 'uint64' || field.type.typeName.startsWith('int') && field.type.typeName !== 'int64') {
        unmarshalBody += `\t\t\t\t\t\t${receiver}.${field.name} = to.Ptr(${field.type.typeName}(v))\n`;
      } else {
        unmarshalBody += `\t\t\t\t\t\t${receiver}.${field.name} = to.Ptr(v)\n`;
      }
      unmarshalBody += '\t\t\t\t\t}\n';
      unmarshalBody += '\t\t\t\t}\n';
      modelDef.SerDe.needsJSONUnpopulate = true;
    } else {
      unmarshalBody += `\t\t\t\terr = unpopulate(val, "${field.name}", &${receiver}.${field.name})\n`;
      modelDef.SerDe.needsJSONUnpopulate = true;
    }
    unmarshalBody += '\t\t\tdelete(rawMsg, key)\n';
  }
  if (addlProps) {
    unmarshalBody += '\t\tdefault:\n';
    unmarshalBody += emitAddlProps('\t', addlProps);
  } else if (options.disallowUnknownFields) {
    unmarshalBody += '\t\tdefault:\n';
    unmarshalBody += `\t\t\terr = fmt.Errorf("unmarshalling type %T, unknown field %q", ${receiver}, key)\n`;
  }
  unmarshalBody += '\t\t}\n';
  unmarshalBody += '\t\tif err != nil {\n';
  unmarshalBody += `\t\t\treturn fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
  unmarshalBody += '\t\t}\n';
  unmarshalBody += '\t}\n'; // end for key, val := range rawMsg
  unmarshalBody += '\treturn nil\n';
  return unmarshalBody;
}