<commit_before>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "src/core/lib/surface/channel.h"

#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

#include <grpc/compression.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>

#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_tracer.h"
#include "src/core/lib/channel/object_registry.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/static_metadata.h"

/** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS.
 *  Avoids needing to take a metadata context lock for sending status
 *  if the status code is <= NUM_CACHED_STATUS_ELEMS.
 *  Sized to allow the most commonly used codes to fit in
 *  (OK, Cancelled, Unknown). */
#define NUM_CACHED_STATUS_ELEMS 3

typedef struct registered_call {
  grpc_mdelem path;
  grpc_mdelem authority;
  struct registered_call* next;
} registered_call;

struct grpc_channel {
  int is_client;
  grpc_compression_options compression_options;
  grpc_mdelem default_authority;

  gpr_atm call_size_estimate;

  gpr_mu registered_call_mu;
  registered_call* registered_calls;

  grpc_core::RefCountedPtr<grpc_core::ChannelTracer> tracer;

  char* target;
};

#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack*)((c) + 1))
#define CHANNEL_FROM_CHANNEL_STACK(channel_stack) \
  (((grpc_channel*)(channel_stack)) - 1)
#define CHANNEL_FROM_TOP_ELEM(top_elem) \
  CHANNEL_FROM_CHANNEL_STACK(grpc_channel_stack_from_top_element(top_elem))

static void destroy_channel(void* arg, grpc_error* error);

grpc_channel* grpc_channel_create_with_builder(
    grpc_channel_stack_builder* builder,
    grpc_channel_stack_type channel_stack_type) {
  char* target = gpr_strdup(grpc_channel_stack_builder_get_target(builder));
  grpc_channel_args* args = grpc_channel_args_copy(
      grpc_channel_stack_builder_get_channel_arguments(builder));
  grpc_channel* channel;
  if (channel_stack_type == GRPC_SERVER_CHANNEL) {
    GRPC_STATS_INC_SERVER_CHANNELS_CREATED();
  } else {
    GRPC_STATS_INC_CLIENT_CHANNELS_CREATED();
  }
  grpc_error* error = grpc_channel_stack_builder_finish(
      builder, sizeof(grpc_channel), 1, destroy_channel, nullptr,
      (void**)&channel);
  if (error != GRPC_ERROR_NONE) {
    gpr_log(GPR_ERROR, "channel stack builder failed: %s",
            grpc_error_string(error));
    GRPC_ERROR_UNREF(error);
    gpr_free(target);
    grpc_channel_args_destroy(args);
    return channel;
  }

  memset(channel, 0, sizeof(*channel));
  channel->target = target;
  channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
  int64_t channel_tracer_max_nodes = 0;  // default to off
  gpr_mu_init(&channel->registered_call_mu);
  channel->registered_calls = nullptr;

  gpr_atm_no_barrier_store(
      &channel->call_size_estimate,
      (gpr_atm)CHANNEL_STACK_FROM_CHANNEL(channel)->call_stack_size);

  grpc_compression_options_init(&channel->compression_options);
  for (size_t i = 0; i < args->num_args; i++) {
    if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
      if (args->args[i].type != GRPC_ARG_STRING) {
        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
                GRPC_ARG_DEFAULT_AUTHORITY);
      } else {
        if (!GRPC_MDISNULL(channel->default_authority)) {
          /* setting this takes precedence over anything else */
          GRPC_MDELEM_UNREF(channel->default_authority);
        }
        channel->default_authority = grpc_mdelem_from_slices(
            GRPC_MDSTR_AUTHORITY,
            grpc_slice_intern(
                grpc_slice_from_static_string(args->args[i].value.string)));
      }
    } else if (0 ==
               strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
      if (args->args[i].type != GRPC_ARG_STRING) {
        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
                GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
      } else {
        if (!GRPC_MDISNULL(channel->default_authority)) {
          /* other ways of setting this (notably ssl) take precedence */
          gpr_log(GPR_ERROR,
                  "%s ignored: default host already set some other way",
                  GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
        } else {
          channel->default_authority = grpc_mdelem_from_slices(
              GRPC_MDSTR_AUTHORITY,
              grpc_slice_intern(
                  grpc_slice_from_static_string(args->args[i].value.string)));
        }
      }
    } else if (0 == strcmp(args->args[i].key,
                           GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
      channel->compression_options.default_level.is_set = true;
      channel->compression_options.default_level.level =
          static_cast<grpc_compression_level>(grpc_channel_arg_get_integer(
              &args->args[i],
              {GRPC_COMPRESS_LEVEL_NONE, GRPC_COMPRESS_LEVEL_NONE,
               GRPC_COMPRESS_LEVEL_COUNT - 1}));
    } else if (0 == strcmp(args->args[i].key,
                           GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
      channel->compression_options.default_algorithm.is_set = true;
      channel->compression_options.default_algorithm.algorithm =
          static_cast<grpc_compression_algorithm>(grpc_channel_arg_get_integer(
              &args->args[i], {GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
                               GRPC_COMPRESS_ALGORITHMS_COUNT - 1}));
    } else if (0 ==
               strcmp(args->args[i].key,
                      GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
      channel->compression_options.enabled_algorithms_bitset =
          (uint32_t)args->args[i].value.integer |
          0x1; /* always support no compression */
    } else if (0 ==
               strcmp(args->args[i].key, GRPC_ARG_CHANNEL_TRACING_MAX_NODES)) {
      GPR_ASSERT(channel_tracer_max_nodes == -1);
      // max_nodes defaults to 10, clamped between 0 and 100.
      const grpc_integer_options options = {10, 0, 100};
      channel_tracer_max_nodes =
          (size_t)grpc_channel_arg_get_integer(&args->args[i], options);
    }
  }

  grpc_channel_args_destroy(args);
  channel->tracer = grpc_core::MakeRefCounted<grpc_core::ChannelTracer>(
      channel_tracer_max_nodes);
  channel->tracer->AddTrace(grpc_slice_from_static_string("Channel created"),
                            GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE);
  return channel;
}

char* grpc_channel_get_trace(grpc_channel* channel, bool recursive) {
  return channel->tracer->RenderTrace(recursive);
}

intptr_t grpc_channel_get_uuid(grpc_channel* channel) {
  return channel->tracer->GetUuid();
}
<commit_msg>Fix objc build<commit_after>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "src/core/lib/surface/channel.h"

#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

#include <grpc/compression.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>

#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_tracer.h"
#include "src/core/lib/channel/object_registry.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/static_metadata.h"

/** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS.
 *  Avoids needing to take a metadata context lock for sending status
 *  if the status code is <= NUM_CACHED_STATUS_ELEMS.
 *  Sized to allow the most commonly used codes to fit in
 *  (OK, Cancelled, Unknown). */
#define NUM_CACHED_STATUS_ELEMS 3

typedef struct registered_call {
  grpc_mdelem path;
  grpc_mdelem authority;
  struct registered_call* next;
} registered_call;

struct grpc_channel {
  int is_client;
  grpc_compression_options compression_options;
  grpc_mdelem default_authority;

  gpr_atm call_size_estimate;

  gpr_mu registered_call_mu;
  registered_call* registered_calls;

  grpc_core::RefCountedPtr<grpc_core::ChannelTracer> tracer;

  char* target;
};

#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack*)((c) + 1))
#define CHANNEL_FROM_CHANNEL_STACK(channel_stack) \
  (((grpc_channel*)(channel_stack)) - 1)
#define CHANNEL_FROM_TOP_ELEM(top_elem) \
  CHANNEL_FROM_CHANNEL_STACK(grpc_channel_stack_from_top_element(top_elem))

static void destroy_channel(void* arg, grpc_error* error);

grpc_channel* grpc_channel_create_with_builder(
    grpc_channel_stack_builder* builder,
    grpc_channel_stack_type channel_stack_type) {
  char* target = gpr_strdup(grpc_channel_stack_builder_get_target(builder));
  grpc_channel_args* args = grpc_channel_args_copy(
      grpc_channel_stack_builder_get_channel_arguments(builder));
  grpc_channel* channel;
  if (channel_stack_type == GRPC_SERVER_CHANNEL) {
    GRPC_STATS_INC_SERVER_CHANNELS_CREATED();
  } else {
    GRPC_STATS_INC_CLIENT_CHANNELS_CREATED();
  }
  grpc_error* error = grpc_channel_stack_builder_finish(
      builder, sizeof(grpc_channel), 1, destroy_channel, nullptr,
      (void**)&channel);
  if (error != GRPC_ERROR_NONE) {
    gpr_log(GPR_ERROR, "channel stack builder failed: %s",
            grpc_error_string(error));
    GRPC_ERROR_UNREF(error);
    gpr_free(target);
    grpc_channel_args_destroy(args);
    return channel;
  }

  memset(channel, 0, sizeof(*channel));
  channel->target = target;
  channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
  size_t channel_tracer_max_nodes = 0;  // default to off
  gpr_mu_init(&channel->registered_call_mu);
  channel->registered_calls = nullptr;

  gpr_atm_no_barrier_store(
      &channel->call_size_estimate,
      (gpr_atm)CHANNEL_STACK_FROM_CHANNEL(channel)->call_stack_size);

  grpc_compression_options_init(&channel->compression_options);
  for (size_t i = 0; i < args->num_args; i++) {
    if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
      if (args->args[i].type != GRPC_ARG_STRING) {
        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
                GRPC_ARG_DEFAULT_AUTHORITY);
      } else {
        if (!GRPC_MDISNULL(channel->default_authority)) {
          /* setting this takes precedence over anything else */
          GRPC_MDELEM_UNREF(channel->default_authority);
        }
        channel->default_authority = grpc_mdelem_from_slices(
            GRPC_MDSTR_AUTHORITY,
            grpc_slice_intern(
                grpc_slice_from_static_string(args->args[i].value.string)));
      }
    } else if (0 ==
               strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
      if (args->args[i].type != GRPC_ARG_STRING) {
        gpr_log(GPR_ERROR, "%s ignored: it must be a string",
                GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
      } else {
        if (!GRPC_MDISNULL(channel->default_authority)) {
          /* other ways of setting this (notably ssl) take precedence */
          gpr_log(GPR_ERROR,
                  "%s ignored: default host already set some other way",
                  GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
        } else {
          channel->default_authority = grpc_mdelem_from_slices(
              GRPC_MDSTR_AUTHORITY,
              grpc_slice_intern(
                  grpc_slice_from_static_string(args->args[i].value.string)));
        }
      }
    } else if (0 == strcmp(args->args[i].key,
                           GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
      channel->compression_options.default_level.is_set = true;
      channel->compression_options.default_level.level =
          static_cast<grpc_compression_level>(grpc_channel_arg_get_integer(
              &args->args[i],
              {GRPC_COMPRESS_LEVEL_NONE, GRPC_COMPRESS_LEVEL_NONE,
               GRPC_COMPRESS_LEVEL_COUNT - 1}));
    } else if (0 == strcmp(args->args[i].key,
                           GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
      channel->compression_options.default_algorithm.is_set = true;
      channel->compression_options.default_algorithm.algorithm =
          static_cast<grpc_compression_algorithm>(grpc_channel_arg_get_integer(
              &args->args[i], {GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
                               GRPC_COMPRESS_ALGORITHMS_COUNT - 1}));
    } else if (0 ==
               strcmp(args->args[i].key,
                      GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
      channel->compression_options.enabled_algorithms_bitset =
          (uint32_t)args->args[i].value.integer |
          0x1; /* always support no compression */
    } else if (0 ==
               strcmp(args->args[i].key, GRPC_ARG_CHANNEL_TRACING_MAX_NODES)) {
      GPR_ASSERT(channel_tracer_max_nodes == 0);
      // max_nodes defaults to 10, clamped between 0 and 100.
      const grpc_integer_options options = {10, 0, 100};
      channel_tracer_max_nodes =
          (size_t)grpc_channel_arg_get_integer(&args->args[i], options);
    }
  }

  grpc_channel_args_destroy(args);
  channel->tracer = grpc_core::MakeRefCounted<grpc_core::ChannelTracer>(
      channel_tracer_max_nodes);
  channel->tracer->AddTrace(grpc_slice_from_static_string("Channel created"),
                            GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE);
  return channel;
}

char* grpc_channel_get_trace(grpc_channel* channel, bool recursive) {
  return channel->tracer->RenderTrace(recursive);
}

intptr_t grpc_channel_get_uuid(grpc_channel* channel) {
  return channel->tracer->GetUuid();
}

{'fraction_non_alphanumeric': 0.1049564591108492, 'fraction_numerical': 0.005499901787468081, 'mean_word_length': 3.6623931623931623, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '795680', 'n_tokens_mistral': 5224, 'n_tokens_neox': 5143, 'n_words': 904}