code: func Serve(opts *ServeOpts) {
  	// since the plugins may not yet be aware of the new protocol, we
  	// automatically wrap the plugins in the grpc shims.
  	if opts.GRPCProviderFunc == nil && opts.ProviderFunc != nil {
  		provider := grpcplugin.NewGRPCProviderServerShim(opts.ProviderFunc())
  		// this is almost always going to be a *schema.Provider, but check that
  		// we got back a valid provider just in case.
  		if provider != nil {
  			opts.GRPCProviderFunc = func() proto.ProviderServer {
  				return provider
  			}
  		}
  	}
  	if opts.GRPCProvisionerFunc == nil && opts.ProvisionerFunc != nil {
  		provisioner := grpcplugin.NewGRPCProvisionerServerShim(opts.ProvisionerFunc())
  		if provisioner != nil {
  			opts.GRPCProvisionerFunc = func() proto.ProvisionerServer {
  				return provisioner
  			}
  		}
  	}
  
  	plugin.Serve(&plugin.ServeConfig{
  		HandshakeConfig:  Handshake,
  		VersionedPlugins: pluginSet(opts),
  		GRPCServer:       plugin.DefaultGRPCServer,
  	})
  }
docs: // Serve serves a plugin. This function never returns and should be the final
  // function called in the main function of the plugin.