docs: void compareRecordTypes(Schema oldSchema,
                                                   Schema newSchema,
                                                   List<Message> messages,
                                                   String name) {
          if(oldSchema == null || newSchema == null || oldSchema.getType() != Schema.Type.RECORD) {
              throw new IllegalArgumentException("Old schema must be RECORD type. Name=" + name
                                                 + ". Type=" + oldSchema);
          }
  
          if(newSchema.getType() != Schema.Type.RECORD) {
              messages.add(new Message(Level.ERROR, "Illegal type change from " + oldSchema.getType()
                                                    + " to " + newSchema.getType() + " for field "
                                                    + name));
              return;
          }
  
          // Check all of the fields in the new schema
          for(Field newField: newSchema.getFields()) {
              String fieldName = newField.name();
              Field oldField = oldSchema.getField(fieldName);
  
              if(oldField == null) {
                  // This is a new field that did not exist in the original
                  // schema.
                  // Check if it is optional or has a default value.
                  if(isOptional(newField)) {
                      if(newField.defaultValue() == null) {
                          messages.add(new Message(Level.INFO, "Added optional field " + name + "."
                                                               + fieldName
                                                               + " with no default value."));
                      } else {
                          messages.add(new Message(Level.INFO, "Added optional field " + name + "."
                                                               + fieldName + " with default value: "
                                                               + newField.defaultValue()));
                      }
                  } else {
                      if(newField.defaultValue() == null) {
                          messages.add(new Message(Level.ERROR, "Added required field " + name + "."
                                                                + fieldName
                                                                + " with no default value."));
                      } else {
                          messages.add(new Message(Level.INFO, "Added required field " + name + "."
                                                               + fieldName + " with default value: "
                                                               + newField.defaultValue()));
                      }
                  }
              } else {
                  // This is a field that existed in the original schema.
  
                  // Check if the field was changed from optional to required or
                  // vice versa.
                  boolean newFieldIsOptional = isOptional(newField);
                  boolean oldFieldIsOptional = isOptional(oldField);
  
                  if(oldFieldIsOptional != newFieldIsOptional) {
                      if(oldFieldIsOptional) {
                          messages.add(new Message(Level.ERROR,
                                                   "Existing field " + name + "." + fieldName
                                                           + " was optional and is now required."));
                      } else {
                          messages.add(new Message(Level.WARN, "Existing field " + name + "."
                                                               + fieldName
                                                               + " was required and is now optional."));
                      }
                  }
  
                  // Recursively compare the nested field types
                  compareTypes(oldField.schema(), newField.schema(), messages, name + "." + fieldName);
  
                  // Check if the default value has been changed
                  if(newField.defaultValue() == null) {
                      if(oldField.defaultValue() != null) {
                          messages.add(new Message(Level.WARN,
                                                   "Removed default value for existing field " + name
                                                           + "." + fieldName
                                                           + ". The old default was: "
                                                           + oldField.defaultValue()));
                      }
                  } else // newField.defaultValue() != null
                  {
                      if(oldField.defaultValue() == null) {
                          messages.add(new Message(Level.WARN,
                                                   "Added a default value for existing field " + name
                                                           + "." + fieldName
                                                           + ". The new default is: "
                                                           + newField.defaultValue()));
                      } else if(!newField.defaultValue().equals(oldField.defaultValue())) {
                          messages.add(new Message(Level.INFO,
                                                   "Changed the default value for existing field "
                                                           + name + "." + fieldName
                                                           + ". The old default was: "
                                                           + oldField.defaultValue()
                                                           + ". The new default is: "
                                                           + newField.defaultValue()));
                      }
                  }
              }
  
              // For all fields in the new schema (whether or not it existed in
              // the old schema), if there is a default value for this field, make
              // sure it is legal.
              if(newField.defaultValue() != null) {
                  checkDefaultValueIsLegal(newField, messages, name + "." + fieldName);
              }
          }
  
          // Check if any fields were removed.
          for(Field oldField: newSchema.getFields()) {
              String fieldName = oldField.name();
              Field newField = newSchema.getField(fieldName);
  
              if(newField == null) {
                  if(isOptional(oldField)) {
                      messages.add(new Message(Level.INFO, "Removed optional field " + name + "."
                                                           + fieldName));
                  } else {
                      messages.add(new Message(Level.WARN, "Removed required field " + name + "."
                                                           + fieldName));
                  }
              }
          }
  
          // Check if indexing was modified or added to any old fields.
          for(Field oldField: oldSchema.getFields()) {
              if(newSchema.getField(oldField.name()) != null) {
                  String oldIndexType = oldField.getProp("indexType");
                  String newIndexType = newSchema.getField(oldField.name()).getProp("indexType");
  
                  // Check if added indexing.
                  if(oldIndexType == null && newIndexType != null) {
                      messages.add(new Message(Level.ERROR,
                                               "Cannot add indexing to "
                                                       + oldField.name()
                                                       + ". Adding indexing to fields created without indexing is not supported."));
                  }
  
                  // Check if changed indexing
                  if(oldIndexType != null && !oldIndexType.equals(newIndexType)) {
                      messages.add(new Message(Level.ERROR,
                                               "Cannot change indexing from "
                                                       + oldIndexType
                                                       + " to "
                                                       + newIndexType
                                                       + " for "
                                                       + oldField.name()
                                                       + ". Changing indexing method is not supported."));
                  }
              }
          }
      }