Return all entities in get_message_entities.

GitOrigin-RevId: b08c7a9ab0cfa9a78e450d5cbf3567203abd7d67
This commit is contained in:
levlam 2020-03-10 03:51:56 +03:00
parent 1068cac8f0
commit 6417510d51
4 changed files with 43 additions and 10 deletions

View File

@ -1908,8 +1908,8 @@ static vector<Slice> find_text_url_entities_v3(Slice text) {
// entities must be valid for the text // entities must be valid for the text
static FormattedText parse_text_url_entities_v3(Slice text, vector<MessageEntity> entities) { static FormattedText parse_text_url_entities_v3(Slice text, vector<MessageEntity> entities) {
// TextUrl and MentionName can't intersect TextUrl entities, // continuous entities can't intersect TextUrl entities,
// so try to find new TextUrl entities only between the predetermined TextUrl and MentionName entities // so try to find new TextUrl entities only between the predetermined continuous entities
FormattedText result; FormattedText result;
int32 result_text_utf16_length = 0; int32 result_text_utf16_length = 0;
@ -2068,7 +2068,7 @@ static FormattedText parse_text_url_entities_v3(Slice text, vector<MessageEntity
part_splittable_entities[index].push_back(entity); part_splittable_entities[index].push_back(entity);
continue; continue;
} }
CHECK(entity.type == MessageEntity::Type::TextUrl || entity.type == MessageEntity::Type::MentionName); CHECK(is_continuous_entity(entity.type));
if (entity.offset > max_end) { if (entity.offset > max_end) {
// found a gap from max_end to entity.offset between predetermined entities // found a gap from max_end to entity.offset between predetermined entities
@ -2137,7 +2137,7 @@ static vector<MessageEntity> find_splittable_entities_v3(Slice text, const vecto
return result; return result;
} }
// entities must be valid and can contain only splittable, TextUrl and MentionName entities // entities must be valid and can contain only splittable and continuous entities
// __italic__ ~~strikethrough~~ **bold** and [text_url](telegram.org) entities are left to be parsed // __italic__ ~~strikethrough~~ **bold** and [text_url](telegram.org) entities are left to be parsed
static FormattedText parse_markdown_v3_without_pre(Slice text, vector<MessageEntity> entities) { static FormattedText parse_markdown_v3_without_pre(Slice text, vector<MessageEntity> entities) {
check_is_sorted(entities); check_is_sorted(entities);
@ -2386,8 +2386,7 @@ FormattedText parse_markdown_v3(FormattedText text) {
for (size_t i = 0; i < text.entities.size(); i++) { for (size_t i = 0; i < text.entities.size(); i++) {
auto &entity = text.entities[i]; auto &entity = text.entities[i];
CHECK(is_splittable_entity(entity.type) || is_pre_entity(entity.type) || CHECK(is_splittable_entity(entity.type) || is_pre_entity(entity.type) || is_continuous_entity(entity.type));
entity.type == MessageEntity::Type::TextUrl || entity.type == MessageEntity::Type::MentionName);
if (is_pre_entity(entity.type)) { if (is_pre_entity(entity.type)) {
CHECK(entity.offset >= max_end); CHECK(entity.offset >= max_end);
CHECK(i + 1 == text.entities.size() || text.entities[i + 1].offset >= entity.offset + entity.length); CHECK(i + 1 == text.entities.size() || text.entities[i + 1].offset >= entity.offset + entity.length);
@ -2836,7 +2835,8 @@ vector<tl_object_ptr<secret_api::MessageEntity>> get_input_secret_message_entiti
} }
Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contacts_manager, Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contacts_manager,
vector<tl_object_ptr<td_api::textEntity>> &&input_entities) { vector<tl_object_ptr<td_api::textEntity>> &&input_entities,
bool allow_all) {
vector<MessageEntity> entities; vector<MessageEntity> entities;
for (auto &entity : input_entities) { for (auto &entity : input_entities) {
if (entity == nullptr || entity->type_ == nullptr) { if (entity == nullptr || entity->type_ == nullptr) {
@ -2845,13 +2845,44 @@ Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contac
switch (entity->type_->get_id()) { switch (entity->type_->get_id()) {
case td_api::textEntityTypeMention::ID: case td_api::textEntityTypeMention::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::Mention, entity->offset_, entity->length_);
}
break;
case td_api::textEntityTypeHashtag::ID: case td_api::textEntityTypeHashtag::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::Hashtag, entity->offset_, entity->length_);
}
break;
case td_api::textEntityTypeBotCommand::ID: case td_api::textEntityTypeBotCommand::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::BotCommand, entity->offset_, entity->length_);
}
break;
case td_api::textEntityTypeUrl::ID: case td_api::textEntityTypeUrl::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::Url, entity->offset_, entity->length_);
}
break;
case td_api::textEntityTypeEmailAddress::ID: case td_api::textEntityTypeEmailAddress::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::EmailAddress, entity->offset_, entity->length_);
}
break;
case td_api::textEntityTypeCashtag::ID: case td_api::textEntityTypeCashtag::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::Cashtag, entity->offset_, entity->length_);
}
break;
case td_api::textEntityTypePhoneNumber::ID: case td_api::textEntityTypePhoneNumber::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::PhoneNumber, entity->offset_, entity->length_);
}
break;
case td_api::textEntityTypeBankCardNumber::ID: case td_api::textEntityTypeBankCardNumber::ID:
if (allow_all) {
entities.emplace_back(MessageEntity::Type::BankCardNumber, entity->offset_, entity->length_);
}
break; break;
case td_api::textEntityTypeBold::ID: case td_api::textEntityTypeBold::ID:
entities.emplace_back(MessageEntity::Type::Bold, entity->offset_, entity->length_); entities.emplace_back(MessageEntity::Type::Bold, entity->offset_, entity->length_);

View File

@ -124,7 +124,8 @@ inline bool operator!=(const FormattedText &lhs, const FormattedText &rhs) {
const std::unordered_set<Slice, SliceHash> &get_valid_short_usernames(); const std::unordered_set<Slice, SliceHash> &get_valid_short_usernames();
Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contacts_manager, Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contacts_manager,
vector<tl_object_ptr<td_api::textEntity>> &&input_entities); vector<tl_object_ptr<td_api::textEntity>> &&input_entities,
bool allow_all = false);
vector<tl_object_ptr<td_api::textEntity>> get_text_entities_object(const vector<MessageEntity> &entities); vector<tl_object_ptr<td_api::textEntity>> get_text_entities_object(const vector<MessageEntity> &entities);

View File

@ -7560,7 +7560,7 @@ td_api::object_ptr<td_api::Object> Td::do_static_request(td_api::parseMarkdown &
return make_error(400, "Text must be non-empty"); return make_error(400, "Text must be non-empty");
} }
auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_)); auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_), true);
if (r_entities.is_error()) { if (r_entities.is_error()) {
return make_error(400, r_entities.error().message()); return make_error(400, r_entities.error().message());
} }

View File

@ -1493,7 +1493,8 @@ TEST(MessageEntities, parse_markdown_v3) {
td::vector<td::MessageEntity::Type> types{ td::vector<td::MessageEntity::Type> types{
td::MessageEntity::Type::Bold, td::MessageEntity::Type::Italic, td::MessageEntity::Type::Underline, td::MessageEntity::Type::Bold, td::MessageEntity::Type::Italic, td::MessageEntity::Type::Underline,
td::MessageEntity::Type::Strikethrough, td::MessageEntity::Type::Code, td::MessageEntity::Type::Pre, td::MessageEntity::Type::Strikethrough, td::MessageEntity::Type::Code, td::MessageEntity::Type::Pre,
td::MessageEntity::Type::PreCode, td::MessageEntity::Type::TextUrl, td::MessageEntity::Type::MentionName}; td::MessageEntity::Type::PreCode, td::MessageEntity::Type::TextUrl, td::MessageEntity::Type::MentionName,
td::MessageEntity::Type::Cashtag};
for (size_t test_n = 0; test_n < 1000; test_n++) { for (size_t test_n = 0; test_n < 1000; test_n++) {
td::string str; td::string str;
int part_n = td::Random::fast(1, 200); int part_n = td::Random::fast(1, 200);