code: private Method getEncodeMethod(TypeToken<?> outputType, Schema schema) {
      String key = String.format("%s%s", normalizeTypeName(outputType), schema.getSchemaHash());
  
      Method method = encodeMethods.get(key);
      if (method != null) {
        return method;
      }
  
      // Generate the encode method (value, encoder, schema, set)
      TypeToken<?> callOutputType = getCallTypeToken(outputType, schema);
      String methodName = String.format("encode%s", key);
      method = getMethod(void.class, methodName, callOutputType.getRawType(),
                         Encoder.class, Schema.class, Set.class);
  
      // Put the method into map first before generating the body in order to support recursive data type.
      encodeMethods.put(key, method);
  
      String methodSignature = Signatures.getMethodSignature(method, new TypeToken[]{ callOutputType, null, null,
                                                                                new TypeToken<Set<Object>>() { }});
      GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PRIVATE, method, methodSignature,
                                                 new Type[]{Type.getType(IOException.class)}, classWriter);
  
      generateEncodeBody(mg, schema, outputType, 0, 1, 2, 3);
      mg.returnValue();
      mg.endMethod();
  
      return method;
    }
docs: Returns the encode method for the given type and schema. The same method will be returned if the same
  type and schema has been passed to the method before.
  
  @param outputType Type information of the data type for output
  @param schema Schema to use for output.
  @return A method for encoding the given output type and schema.