whole_func_string: function (path, options) {
      return this._getFileId(path).then((id) => {
        return this._getMeta(id).then((meta) => {
          let etagWithoutQuotes;
          if (typeof(meta) === 'object' && typeof(meta.etag) === 'string') {
            etagWithoutQuotes = removeQuotes(meta.etag);
          }
  
          if (options && options.ifNoneMatch && (etagWithoutQuotes === options.ifNoneMatch)) {
            return Promise.resolve({statusCode: 304});
          }
  
          if (!meta.downloadUrl) {
            if (meta.exportLinks && meta.exportLinks['text/html']) {
              // Documents that were generated inside GoogleDocs have no
              // downloadUrl, but you can export them to text/html instead:
              meta.mimeType += ';export=text/html';
              meta.downloadUrl = meta.exportLinks['text/html'];
            } else {
              // empty file
              return Promise.resolve({statusCode: 200, body: '', contentType: meta.mimeType, revision: etagWithoutQuotes});
            }
          }
  
          var params = {
            responseType: 'arraybuffer'
          };        
          return this._request('GET', meta.downloadUrl, params).then((response) => {
            //first encode the response as text, and later check if 
            //text appears to actually be binary data
            return getTextFromArrayBuffer(response.response, 'UTF-8').then(function (responseText) { 
              let body = responseText;
              if (meta.mimeType.match(/^application\/json/)) {
                try {
                  body = JSON.parse(body);
                } catch(e) {
                  // body couldn't be parsed as JSON, so we'll just return it as is
                }
              } else {
                if (shouldBeTreatedAsBinary(responseText, meta.mimeType)) {
                  //return unprocessed response 
                  body = response.response;
                }
              }
  
              return {statusCode: 200, body: body, contentType: meta.mimeType, revision: etagWithoutQuotes};
            });
          });
        });
      });
    }
func_code_string: function (path, options) {
      return this._getFileId(path).then((id) => {
        return this._getMeta(id).then((meta) => {
          let etagWithoutQuotes;
          if (typeof(meta) === 'object' && typeof(meta.etag) === 'string') {
            etagWithoutQuotes = removeQuotes(meta.etag);
          }
  
          if (options && options.ifNoneMatch && (etagWithoutQuotes === options.ifNoneMatch)) {
            return Promise.resolve({statusCode: 304});
          }
  
          if (!meta.downloadUrl) {
            if (meta.exportLinks && meta.exportLinks['text/html']) {
              // Documents that were generated inside GoogleDocs have no
              // downloadUrl, but you can export them to text/html instead:
              meta.mimeType += ';export=text/html';
              meta.downloadUrl = meta.exportLinks['text/html'];
            } else {
              // empty file
              return Promise.resolve({statusCode: 200, body: '', contentType: meta.mimeType, revision: etagWithoutQuotes});
            }
          }
  
          var params = {
            responseType: 'arraybuffer'
          };        
          return this._request('GET', meta.downloadUrl, params).then((response) => {
            //first encode the response as text, and later check if 
            //text appears to actually be binary data
            return getTextFromArrayBuffer(response.response, 'UTF-8').then(function (responseText) { 
              let body = responseText;
              if (meta.mimeType.match(/^application\/json/)) {
                try {
                  body = JSON.parse(body);
                } catch(e) {
                  // body couldn't be parsed as JSON, so we'll just return it as is
                }
              } else {
                if (shouldBeTreatedAsBinary(responseText, meta.mimeType)) {
                  //return unprocessed response 
                  body = response.response;
                }
              }
  
              return {statusCode: 200, body: body, contentType: meta.mimeType, revision: etagWithoutQuotes};
            });
          });
        });
      });
    }
func_documentation_string: Request a file.
  
  @param {string} path - File path
  @param {Object} options
  @param {string} [options.ifNoneMath] - Only return the file if its ETag
  doesn't match the given string
  @returns {Promise} Resolves with an object containing the status code,
  body, content-type and revision
  
  @private