function generateVertexShaderLines(customShader, attributesByName) {
  if (!defined(customShader.vertexShaderText)) {
    return { enabled: false };
  }

  const primitiveAttributes = customShader.usedVariablesVertex.attributeSet;
  const addToShader = getPrimitiveAttributesUsedInShader(
    attributesByName,
    primitiveAttributes,
    false,
  );
  const needsDefault = getAttributesNeedingDefaults(
    attributesByName,
    primitiveAttributes,
    false,
  );

  let vertexInitialization;
  const attributeFields = [];
  const initializationLines = [];
  for (const variableName in addToShader) {
    if (!addToShader.hasOwnProperty(variableName)) {
      continue;
    }
    const attributeInfo = addToShader[variableName];
    const attributeField = [attributeInfo.glslType, variableName];
    attributeFields.push(attributeField);

    // Initializing attribute structs are just a matter of copying the
    // attribute or varying: E.g.:
    // "    vsInput.attributes.position = a_position;"
    vertexInitialization = `vsInput.attributes.${variableName} = attributes.${variableName};`;
    initializationLines.push(vertexInitialization);
  }

  for (let i = 0; i < needsDefault.length; i++) {
    const variableName = needsDefault[i];
    const attributeDefaults = inferAttributeDefaults(variableName);
    if (!defined(attributeDefaults)) {
      CustomShaderPipelineStage._oneTimeWarning(
        "CustomShaderPipelineStage.incompatiblePrimitiveVS",
        `Primitive is missing attribute ${variableName}, disabling custom vertex shader`,
      );
      // This primitive isn't compatible with the shader. Return early
      // to skip the vertex shader
      return { enabled: false };
    }

    attributeFields.push(attributeDefaults.attributeField);
    vertexInitialization = `vsInput.attributes.${variableName} = ${attributeDefaults.value};`;
    initializationLines.push(vertexInitialization);
  }

  return {
    enabled: true,
    attributeFields: attributeFields,
    initializationLines: initializationLines,
  };
}
@private
@param {CustomShader} customShader
@param {Object<string, ModelComponents.Attribute>} attributesByName
@returns {object}