function parseStyle(style) {
  const context = newCompilationContext();
  const pipeline = [];

  if (style.color !== undefined) {
    const color = expressionToGlsl(context, style.color, ColorType);
    pipeline.push(`color = ${color};`);
  }

  const variableNames = Object.keys(context.variables);
  if (variableNames.length > 1 && !style.variables) {
    throw new Error(
      `Missing variables in style (expected ${context.variables})`,
    );
  }

  /** @type {Object<string,import("../webgl/Helper").UniformValue>} */
  const uniforms = {};

  for (const variableName of variableNames) {
    if (!(variableName in style.variables)) {
      throw new Error(`Missing '${variableName}' in style variables`);
    }

    const uniformName = uniformNameForVariable(variableName);
    uniforms[uniformName] = function () {
      let value = style.variables[variableName];
      if (typeof value === 'string') {
        value = getStringNumberEquivalent(value);
      }
      return value !== undefined ? value : -9999999; // to avoid matching with the first string literal
    };
  }

  const uniformDeclarations = Object.keys(uniforms).map(function (name) {
    return `uniform float ${name};`;
  });

  const functionDefintions = Object.keys(context.functions).map(
    function (name) {
      return context.functions[name];
    },
  );

  const particleColorFragmentShader = `
    #ifdef GL_FRAGMENT_PRECISION_HIGH
    precision highp float;
    #else
    precision mediump float;
    #endif

    uniform sampler2D ${U.VELOCITY_TEXTURE};
    uniform float ${U.MAX_SPEED};
    uniform vec2 ${U.ROTATION};

    ${uniformDeclarations.join('\n')}

    varying vec2 ${V.POSITION};
    
    ${functionDefintions.join('\n')}

    void main() {
      vec4 velocityColor = texture2D(${U.VELOCITY_TEXTURE}, ${V.POSITION});

      float vx = mix(-${U.MAX_SPEED}, ${U.MAX_SPEED}, velocityColor.r);
      float vy = mix(-${U.MAX_SPEED}, ${U.MAX_SPEED}, velocityColor.g);

      vec2 velocity = vec2(
        vx * ${U.ROTATION}.x - vy * ${U.ROTATION}.y,
        vx * ${U.ROTATION}.y + vy * ${U.ROTATION}.x
      );

      float a_prop_speed = length(velocity);

      vec4 color;

      ${pipeline.join('\n')}

      if (color.a == 0.0) {
        discard;
      }

      gl_FragColor = color;
    }
  `;

  return {
    tileVertexShader,
    tileFragmentShader,
    particleColorVertexShader,
    particleColorFragmentShader,
    particlePositionVertexShader: quadVertexShader,
    particlePositionFragmentShader,
    textureVertexShader: quadVertexShader,
    textureFragmentShader,
  };
}
@param {Style} style The layer style.
@return {ParsedStyle} Shaders and uniforms generated from the style.