docs: function RecordType(schema, opts) {
    // Force creation of the options object in case we need to register this
    // record's name.
    opts = opts || {};
  
    // Save the namespace to restore it as we leave this record's scope.
    var namespace = opts.namespace;
    if (schema.namespace !== undefined) {
      opts.namespace = schema.namespace;
    } else if (schema.name) {
      // Fully qualified names' namespaces are used when no explicit namespace
      // attribute was specified.
      var match = /^(.*)\.[^.]+$/.exec(schema.name);
      if (match) {
        opts.namespace = match[1];
      }
    }
    Type.call(this, schema, opts);
  
    if (!Array.isArray(schema.fields)) {
      throw new Error(f('non-array record fields: %j', schema.fields));
    }
    if (utils.hasDuplicates(schema.fields, function (f) { return f.name; })) {
      throw new Error(f('duplicate field name: %j', schema.fields));
    }
    this._fieldsByName = {};
    this.fields = Object.freeze(schema.fields.map(function (f) {
      var field = new Field(f, opts);
      this._fieldsByName[field.name] = field;
      return field;
    }, this));
    this._branchConstructor = this._createBranchConstructor();
    this._isError = schema.type === 'error';
    this.recordConstructor = this._createConstructor(opts.errorStackTraces);
    this._read = this._createReader();
    this._skip = this._createSkipper();
    this._write = this._createWriter();
    this._check = this._createChecker();
  
    opts.namespace = namespace;
    Object.freeze(this);
  }