<commit_before>// Copyright (c) 2006- Facebook
// Distributed under the Thrift Software License
//
// See accompanying file LICENSE or visit the Thrift site at:
// http://developers.facebook.com/thrift/

#ifndef T_TYPE_H
#define T_TYPE_H

#include <string>
#include <cstring>
#include "t_doc.h"

// What's worse?  This, or making a src/parse/non_inlined.cc?
#include "md5.h"

class t_program;

/**
 * Generic representation of a thrift type. These objects are used by the
 * parser module to build up a tree of object that are all explicitly typed.
 * The generic t_type class exports a variety of useful methods that are
 * used by the code generator to branch based upon different handling for the
 * various types.
 *
 * @author <NAME> <<EMAIL>>
 */
class t_type : public t_doc {
 public:
  virtual ~t_type() {}

  virtual void set_name(const std::string& name) {
    name_ = name;
  }

  virtual const std::string& get_name() const {
    return name_;
  }

  virtual bool is_void()      const { return false; }
  virtual bool is_base_type() const { return false; }
  virtual bool is_string()    const { return false; }
  virtual bool is_bool()      const { return false; }
  virtual bool is_typedef()   const { return false; }
  virtual bool is_enum()      const { return false; }
  virtual bool is_struct()    const { return false; }
  virtual bool is_xception()  const { return false; }
  virtual bool is_container() const { return false; }
  virtual bool is_list()      const { return false; }
  virtual bool is_set()       const { return false; }
  virtual bool is_map()       const { return false; }
  virtual bool is_service()   const { return false; }

  t_program* get_program() {
    return program_;
  }


  // Return a string that uniquely identifies this type
  // from any other thrift type in the world, as far as
  // TDenseProtocol is concerned.
  // We don't cache this, which is a little sloppy,
  // but the compiler is so fast that it doesn't really matter.
  virtual std::string get_fingerprint_material() const = 0;

  // Fingerprint should change whenever (and only when)
  // the encoding via TDenseProtocol changes.
  static const int fingerprint_len = 16;

  // Call this before trying get_*_fingerprint().
  virtual void generate_fingerprint() {
    std::string material = get_fingerprint_material();
    MD5_CTX ctx;
    MD5Init(&ctx);
    MD5Update(&ctx, (unsigned char*)(material.data()), material.size());
    MD5Final(fingerprint_, &ctx);
  }

  bool has_fingerprint() const {
    for (int i = 0; i < fingerprint_len; i++) {
      if (fingerprint_[i] != 0) {
        return true;
      }
    }
    return false;
  }

  const uint8_t* get_binary_fingerprint() const {
    return fingerprint_;
  }

  std::string get_ascii_fingerprint() const {
    std::string rv;
    const uint8_t* fp = get_binary_fingerprint();
    for (int i = 0; i < fingerprint_len; i++) {
      rv += byte_to_hex(fp[i]);
    }
    return rv;
  }

  // This function will break (maybe badly) unless 0 <= num <= 16.
  static char nybble_to_xdigit(int num) {
    if (num < 10) {
      return '0' + num;
    } else {
      return 'A' + num - 10;
    }
  }

  static std::string byte_to_hex(uint8_t byte) {
    std::string rv;
    rv += nybble_to_xdigit(byte >> 4);
    rv += nybble_to_xdigit(byte & 0x0f);
    return rv;
  }


 protected:
  t_type() {
    memset(fingerprint_, 0, sizeof(fingerprint_));
  }

  t_type(t_program* program) :
    program_(program)
  {
    memset(fingerprint_, 0, sizeof(fingerprint_));
  }

  t_type(t_program* program, std::string name) :
    program_(program),
    name_(name)
  {
    memset(fingerprint_, 0, sizeof(fingerprint_));
  }

  t_type(std::string name) :
    name_(name)
  {<commit_msg>Fix a segfault in the compiler.<commit_after>// Copyright (c) 2006- Facebook
// Distributed under the Thrift Software License
//
// See accompanying file LICENSE or visit the Thrift site at:
// http://developers.facebook.com/thrift/

#ifndef T_TYPE_H
#define T_TYPE_H

#include <string>
#include <cstring>
#include "t_doc.h"

// What's worse?  This, or making a src/parse/non_inlined.cc?
#include "md5.h"

class t_program;

/**
 * Generic representation of a thrift type. These objects are used by the
 * parser module to build up a tree of object that are all explicitly typed.
 * The generic t_type class exports a variety of useful methods that are
 * used by the code generator to branch based upon different handling for the
 * various types.
 *
 * @author <NAME> <<EMAIL>>
 */
class t_type : public t_doc {
 public:
  virtual ~t_type() {}

  virtual void set_name(const std::string& name) {
    name_ = name;
  }

  virtual const std::string& get_name() const {
    return name_;
  }

  virtual bool is_void()      const { return false; }
  virtual bool is_base_type() const { return false; }
  virtual bool is_string()    const { return false; }
  virtual bool is_bool()      const { return false; }
  virtual bool is_typedef()   const { return false; }
  virtual bool is_enum()      const { return false; }
  virtual bool is_struct()    const { return false; }
  virtual bool is_xception()  const { return false; }
  virtual bool is_container() const { return false; }
  virtual bool is_list()      const { return false; }
  virtual bool is_set()       const { return false; }
  virtual bool is_map()       const { return false; }
  virtual bool is_service()   const { return false; }

  t_program* get_program() {
    return program_;
  }


  // Return a string that uniquely identifies this type
  // from any other thrift type in the world, as far as
  // TDenseProtocol is concerned.
  // We don't cache this, which is a little sloppy,
  // but the compiler is so fast that it doesn't really matter.
  virtual std::string get_fingerprint_material() const = 0;

  // Fingerprint should change whenever (and only when)
  // the encoding via TDenseProtocol changes.
  static const int fingerprint_len = 16;

  // Call this before trying get_*_fingerprint().
  virtual void generate_fingerprint() {
    std::string material = get_fingerprint_material();
    MD5_CTX ctx;
    MD5Init(&ctx);
    MD5Update(&ctx, (unsigned char*)(material.data()), material.size());
    MD5Final(fingerprint_, &ctx);
  }

  bool has_fingerprint() const {
    for (int i = 0; i < fingerprint_len; i++) {
      if (fingerprint_[i] != 0) {
        return true;
      }
    }
    return false;
  }

  const uint8_t* get_binary_fingerprint() const {
    return fingerprint_;
  }

  std::string get_ascii_fingerprint() const {
    std::string rv;
    const uint8_t* fp = get_binary_fingerprint();
    for (int i = 0; i < fingerprint_len; i++) {
      rv += byte_to_hex(fp[i]);
    }
    return rv;
  }

  // This function will break (maybe badly) unless 0 <= num <= 16.
  static char nybble_to_xdigit(int num) {
    if (num < 10) {
      return '0' + num;
    } else {
      return 'A' + num - 10;
    }
  }

  static std::string byte_to_hex(uint8_t byte) {
    std::string rv;
    rv += nybble_to_xdigit(byte >> 4);
    rv += nybble_to_xdigit(byte & 0x0f);
    return rv;
  }


 protected:
  t_type() :
    program_(NULL)
  {
    memset(fingerprint_, 0, sizeof(fingerprint_));
  }

  t_type(t_program* program) :
    program_(program)
  {
    memset(fingerprint_, 0, sizeof(fingerprint_));
  }

  t_type(t_program* program, std::string name) :
    program_(program),
    name_(name)
  {
    memset(fingerprint_, 0, sizeof(fingerprint_));
  }

  t_type(std::string name) :
    program_(NULL),
    name_(name)
  {
{'fraction_non_alphanumeric': 0.11066826092732829, 'fraction_numerical': 0.008502723528630265, 'mean_word_length': 3.1317233809001097, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5978205', 'n_tokens_mistral': 2515, 'n_tokens_neox': 2369, 'n_words': 789}