docs: function read(str) {
    var schema;
    if (typeof str == 'string' && ~str.indexOf(path.sep) && files.existsSync(str)) {
      // Try interpreting `str` as path to a file contain a JSON schema or an IDL
      // protocol. Note that we add the second check to skip primitive references
      // (e.g. `"int"`, the most common use-case for `avro.parse`).
      var contents = files.readFileSync(str, {encoding: 'utf8'});
      try {
        return JSON.parse(contents);
      } catch (err) {
        var opts = {importHook: files.createSyncImportHook()};
        assembleProtocol(str, opts, function (err, protocolSchema) {
          schema = err ? contents : protocolSchema;
        });
      }
    } else {
      schema = str;
    }
    if (typeof schema != 'string' || schema === 'null') {
      // This last predicate is to allow `read('null')` to work similarly to
      // `read('int')` and other primitives (null needs to be handled separately
      // since it is also a valid JSON identifier).
      return schema;
    }
    try {
      return JSON.parse(schema);
    } catch (err) {
      try {
        return Reader.readProtocol(schema);
      } catch (err) {
        try {
          return Reader.readSchema(schema);
        } catch (err) {
          return schema;
        }
      }
    }
  }