<commit_before>
{%partial doc .%}
NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) {
  {%partial guardArguments .%}
  if (info.Length() == {{args|jsArgsCount}} || !info[{{args|jsArgsCount}}]->IsFunction()) {
    return Nan::ThrowError("Callback is required and must be a Function.");
  }

  {{ cppFunctionName }}Baton* baton = new {{ cppFunctionName }}Baton;

  baton->error_code = GIT_OK;
  baton->error = NULL;

  {%each args|argsInfo as arg %}
    {%if arg.globalPayload %}
      {{ cppFunctionName }}_globalPayload* globalPayload = new {{ cppFunctionName }}_globalPayload;
    {%endif%}
  {%endeach%}

  {%each args|argsInfo as arg %}
    {%if not arg.isReturn %}
      {%if arg.isSelf %}
        baton->{{ arg.name }} = Nan::ObjectWrap::Unwrap<{{ arg.cppClassName }}>(info.This())->GetValue();
      {%elsif arg.isCallbackFunction %}
        if (!info[{{ arg.jsArg }}]->IsFunction()) {
          baton->{{ arg.name }} = NULL;
        {%if arg.payload.globalPayload %}
          globalPayload->{{ arg.name }} = NULL;
        {%else%}
          // NOTE this is a dead path
          baton->{{ arg.payload.name }} = NULL;
        {%endif%}
        }
        else {
          baton->{{ arg.name}} = {{ cppFunctionName }}_{{ arg.name }}_cppCallback;
          {%if arg.payload.globalPayload %}
            globalPayload->{{ arg.name }} = new Nan::Callback(info[{{ arg.jsArg }}].As<Function>());
          {%else%}
            // NOTE this is a dead path
            baton->{{ arg.payload.name }} = new Nan::Callback(info[{{ arg.jsArg }}].As<Function>());
          {%endif%}
        }
      {%elsif arg.payloadFor %}
        {%if arg.globalPayload %}
          baton->{{ arg.name }} = globalPayload;
        {%endif%}
      {%elsif arg.name %}
        {%partial convertFromV8 arg%}
        {%if not arg.payloadFor %}
          baton->{{ arg.name }} = from_{{ arg.name }};
          {%if arg | isOid %}
            baton->{{ arg.name }}NeedsFree = info[{{ arg.jsArg }}]->IsString();
          {%endif%}
        {%endif%}
      {%endif%}
    {%elsif arg.shouldAlloc %}
      baton->{{arg.name}} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|replace '*' '' }}));
      {%if arg.cppClassName == "GitBuf" %}
        baton->{{arg.name}}->ptr = NULL;
        baton->{{arg.name}}->size = baton->{{arg.name}}->asize = 0;
      {%endif%}
    {%endif%}
  {%endeach%}

  Nan::Callback *callback = new Nan::Callback(v8::Local<Function>::Cast(info[{{args|jsArgsCount}}]));
  {{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback);

  {%each args|argsInfo as arg %}
    {%if not arg.isReturn %}
      {%if arg.isSelf %}
        worker->SaveToPersistent("{{ arg.name }}", info.This());
      {%elsif not arg.isCallbackFunction %}
        if (!info[{{ arg.jsArg }}]->IsUndefined() && !info[{{ arg.jsArg }}]->IsNull())
          worker->SaveToPersistent("{{ arg.name }}", Nan::To<v8::Object>(info[{{ arg.jsArg }}]).ToLocalChecked());
      {%endif%}
    {%endif%}
  {%endeach%}

  nodegit::Context *nodegitContext = reinterpret_cast<nodegit::Context *>(info.Data().As<External>()->Value());
  nodegitContext->QueueWorker(worker);
  return;
}

nodegit::LockMaster {{ cppClassName }}::{{ cppFunctionName }}Worker::AcquireLocks() {
  nodegit::LockMaster lockMaster(
    /*asyncAction: */true
    {%each args|argsInfo as arg %}
      {%if arg.cType|isPointer%}
        {%if not arg.cType|isDoublePointer%}
          ,baton->{{ arg.name }}
        {%endif%}
      {%endif%}
    {%endeach%}
  );

  return lockMaster;
}

void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() {
  git_error_clear();

  {%if .|hasReturnType %}
    {{ return.cType }} result = {{ cFunctionName }}(
  {%else%}
    {{ cFunctionName }}(
  {%endif%}
    {%-- Insert Function Arguments --%}
    {%each args|argsInfo as arg %}
      {%-- turn the pointer into a ref --%}
      {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%}
    {%endeach%}
  );

    {%if return.isResultOrError %}
      baton->error_code = result;
      if (result < GIT_OK && git_error_last() != NULL) {
        baton->error = git_error_dup(git_error_last());
      }

    {%elsif return.isErrorCode %}
      baton->error_code = result;

      if (result != GIT_OK && git_error_last() != NULL) {
        baton->error = git_error_dup(git_error_last());
      }

    {%elsif not return.cType == 'void' %}

      baton->result = result;

    {%endif%}
}

void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleErrorCallback() {
  puts("{{ cppClassName }}::{{ cppFunctionName }}Worker::HandleErrorCallback()");
  // inspect the baton for any pointers that have been initialized
  // free any pointers that have been initialized
  if (baton->error) {
    if (baton->error->message) {<commit_msg>Call callback from HandleErrorCallback<commit_after>
{%partial doc .%}
NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) {
  {%partial guardArguments .%}
  if (info.Length() == {{args|jsArgsCount}} || !info[{{args|jsArgsCount}}]->IsFunction()) {
    return Nan::ThrowError("Callback is required and must be a Function.");
  }

  {{ cppFunctionName }}Baton* baton = new {{ cppFunctionName }}Baton;

  baton->error_code = GIT_OK;
  baton->error = NULL;

  {%each args|argsInfo as arg %}
    {%if arg.globalPayload %}
      {{ cppFunctionName }}_globalPayload* globalPayload = new {{ cppFunctionName }}_globalPayload;
    {%endif%}
  {%endeach%}

  {%each args|argsInfo as arg %}
    {%if not arg.isReturn %}
      {%if arg.isSelf %}
        baton->{{ arg.name }} = Nan::ObjectWrap::Unwrap<{{ arg.cppClassName }}>(info.This())->GetValue();
      {%elsif arg.isCallbackFunction %}
        if (!info[{{ arg.jsArg }}]->IsFunction()) {
          baton->{{ arg.name }} = NULL;
        {%if arg.payload.globalPayload %}
          globalPayload->{{ arg.name }} = NULL;
        {%else%}
          // NOTE this is a dead path
          baton->{{ arg.payload.name }} = NULL;
        {%endif%}
        }
        else {
          baton->{{ arg.name}} = {{ cppFunctionName }}_{{ arg.name }}_cppCallback;
          {%if arg.payload.globalPayload %}
            globalPayload->{{ arg.name }} = new Nan::Callback(info[{{ arg.jsArg }}].As<Function>());
          {%else%}
            // NOTE this is a dead path
            baton->{{ arg.payload.name }} = new Nan::Callback(info[{{ arg.jsArg }}].As<Function>());
          {%endif%}
        }
      {%elsif arg.payloadFor %}
        {%if arg.globalPayload %}
          baton->{{ arg.name }} = globalPayload;
        {%endif%}
      {%elsif arg.name %}
        {%partial convertFromV8 arg%}
        {%if not arg.payloadFor %}
          baton->{{ arg.name }} = from_{{ arg.name }};
          {%if arg | isOid %}
            baton->{{ arg.name }}NeedsFree = info[{{ arg.jsArg }}]->IsString();
          {%endif%}
        {%endif%}
      {%endif%}
    {%elsif arg.shouldAlloc %}
      baton->{{arg.name}} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|replace '*' '' }}));
      {%if arg.cppClassName == "GitBuf" %}
        baton->{{arg.name}}->ptr = NULL;
        baton->{{arg.name}}->size = baton->{{arg.name}}->asize = 0;
      {%endif%}
    {%endif%}
  {%endeach%}

  Nan::Callback *callback = new Nan::Callback(v8::Local<Function>::Cast(info[{{args|jsArgsCount}}]));
  {{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback);

  {%each args|argsInfo as arg %}
    {%if not arg.isReturn %}
      {%if arg.isSelf %}
        worker->SaveToPersistent("{{ arg.name }}", info.This());
      {%elsif not arg.isCallbackFunction %}
        if (!info[{{ arg.jsArg }}]->IsUndefined() && !info[{{ arg.jsArg }}]->IsNull())
          worker->SaveToPersistent("{{ arg.name }}", Nan::To<v8::Object>(info[{{ arg.jsArg }}]).ToLocalChecked());
      {%endif%}
    {%endif%}
  {%endeach%}

  nodegit::Context *nodegitContext = reinterpret_cast<nodegit::Context *>(info.Data().As<External>()->Value());
  nodegitContext->QueueWorker(worker);
  return;
}

nodegit::LockMaster {{ cppClassName }}::{{ cppFunctionName }}Worker::AcquireLocks() {
  nodegit::LockMaster lockMaster(
    /*asyncAction: */true
    {%each args|argsInfo as arg %}
      {%if arg.cType|isPointer%}
        {%if not arg.cType|isDoublePointer%}
          ,baton->{{ arg.name }}
        {%endif%}
      {%endif%}
    {%endeach%}
  );

  return lockMaster;
}

void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() {
  git_error_clear();

  {%if .|hasReturnType %}
    {{ return.cType }} result = {{ cFunctionName }}(
  {%else%}
    {{ cFunctionName }}(
  {%endif%}
    {%-- Insert Function Arguments --%}
    {%each args|argsInfo as arg %}
      {%-- turn the pointer into a ref --%}
      {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%}
    {%endeach%}
  );

    {%if return.isResultOrError %}
      baton->error_code = result;
      if (result < GIT_OK && git_error_last() != NULL) {
        baton->error = git_error_dup(git_error_last());
      }

    {%elsif return.isErrorCode %}
      baton->error_code = result;

      if (result != GIT_OK && git_error_last() != NULL) {
        baton->error = git_error_dup(git_error_last());
      }

    {%elsif not return.cType == 'void' %}

      baton->result = result;

    {%endif%}
}

void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleErrorCallback() {
  puts("{{ cppClassName }}::{{ cppFunctionName }}Worker::HandleErrorCallback()");

  v8::Local<v8::Object> err = Nan::To<v8::Object>(Nan::Error(ErrorMessage())).ToLocalChecked();
  Nan::Set(err, Nan::New("errorFunction").ToLocalChecked(), Nan::New("{{ jsClassName }}.{{ jsFunctionName }}").ToLocalChecked());
  v8::Local<v8::Value> argv[1] = {
    err
  };
  callback->Call(1, argv, async_resource);

  // inspect the baton for any pointers that have been initialized
  // free any pointers that have been initialized
  if (baton->error) {
    if (baton->error->message) {
{'fraction_non_alphanumeric': 0.1988, 'fraction_numerical': 0.0015, 'mean_word_length': 2.9607920792079208, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2131155', 'n_tokens_mistral': 3466, 'n_tokens_neox': 3234, 'n_words': 670}