Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++ Generation: New feature to sequential usage + tests #56

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d7bd3b1
and magic static
Brat-vseznamus Aug 13, 2024
f11cb2e
remove size from grow_buffer in cpp helpers
Brat-vseznamus Aug 13, 2024
5d33ceb
fix mistake from prev commit
Brat-vseznamus Aug 13, 2024
f18ca08
little fix with func
Brat-vseznamus Sep 26, 2024
b82be3f
add cpp basic io interaction
Brat-vseznamus Nov 15, 2024
e938acc
move to new basictl
Brat-vseznamus Nov 19, 2024
8772c69
update tests + basictl string impl
Brat-vseznamus Nov 20, 2024
fef6505
forgot helpers
Brat-vseznamus Nov 20, 2024
f5063c6
cases_ and schema_ cpp gen update
Brat-vseznamus Nov 20, 2024
724bf32
+ schema remove
Brat-vseznamus Nov 20, 2024
56c609a
add last release after read + color all tests passed
Brat-vseznamus Nov 20, 2024
2df4a58
default timeout in tl clients
hrissan Aug 22, 2024
0dbeed1
tiny fix
hrissan Aug 22, 2024
ba506b7
tiny tweak
hrissan Aug 22, 2024
7d3b7c4
tiny twaks
hrissan Aug 22, 2024
7c8a3cb
linter happy
hrissan Aug 22, 2024
d7261bb
slightly modified logic of tinestamp
hrissan Aug 22, 2024
23dc568
generator and schema version available through meta, new RPC code gen…
hrissan Sep 20, 2024
2387f3d
add new feature to meta.Function
Brat-vseznamus Oct 28, 2024
2abfa2d
updated goldmaster
Brat-vseznamus Oct 28, 2024
4a68452
update ContainsUnion for Maybe
Brat-vseznamus Oct 28, 2024
a3d4c4e
update goldmaster after prev fix
Brat-vseznamus Oct 28, 2024
798a565
moved From interFACE TO tlitem data
Brat-vseznamus Oct 28, 2024
f9d697f
update goldmaster
Brat-vseznamus Oct 28, 2024
7820d1c
fix logic for detection unions with adding visitedNodes
Brat-vseznamus Oct 29, 2024
bfead87
add specific list type add method which returns it
Brat-vseznamus Oct 29, 2024
9c4d806
update goldmaster
Brat-vseznamus Oct 29, 2024
1700bea
forgot to push new files
Brat-vseznamus Oct 29, 2024
0871cf7
add test for invariant
Brat-vseznamus Oct 29, 2024
8d6e24e
add enum test for invariant
Brat-vseznamus Oct 29, 2024
a0c87b1
forgot again
Brat-vseznamus Oct 29, 2024
19593eb
add HasUnionTypesInArguments
Brat-vseznamus Oct 29, 2024
c0815c7
add new function to test
Brat-vseznamus Oct 29, 2024
18ba810
update goldmaster
Brat-vseznamus Oct 29, 2024
ad6a25f
add formal model to tl on Arend
Brat-vseznamus Nov 13, 2024
d30f9d9
small refactor
Brat-vseznamus Nov 16, 2024
c0ed278
new linter
hrissan Sep 20, 2024
f612670
documentation
hrissan Nov 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,4 @@ cpp:
.PHONY: check
check: build
@go test $(shell go list ./cmd/... ./internal/... ./pkg/... | grep -v /internal/tlcodegen/test/gen/)
@go run honnef.co/go/tools/cmd/staticcheck@v0.4.7 ./... # update version together with github actions
@go run honnef.co/go/tools/cmd/staticcheck@v0.5.1 ./... # update version together with github actions
109 changes: 109 additions & 0 deletions docs/go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Go генератор

tlgen детерминистский и генерирует при повторном запуске один и тот же код, так что
сгенерированный код можно добавлять в систему контроля версий.

По-умолчанию все комбинаторы генерируются в один internal пакет, плюс для каждого
namespace TL генерируется пакет с алиасами. Это сделано потому, что Go не поддерживает рекурсивные зависимости между пакетами, а TL поддерживает.

Для очень больших TL-файлов, содержащих тысячи комбинаторов, можно передать флаг --split-internal, тогда каждый тип помещается в собственный internal пакет.
Затем пакеты для типов, рекурсивно использующих друг друга, обьединяются.
Это сделано для того, чтобы при изменении одного комбинатора TL не приходилось перекомпилировать код большинства комбинаторов.

Также tlgen поддерживает опцию --typesWhiteList, если вам нужна только часть namespace или комбинаторов, то можно явно указать их имена.

# шаблоны

TL-шаблоны полностью инстанцируются (для каждой использованной комбинации аргументов).

Так что pair<int, int> pair<long, long> превращаются в PairIntInt и PairLongLong.


# простые типы

Отображаются в соответствующие типы Go

Nat (#) в uint32, int в int32, long в int64, Bool в bool.

String в string или []byte (В так называемые Bytes-версиях типов)

# векторы и туплы

Отображаются в массивы (если размер фиксирован), либо в слайсы.

Отображение в массивы важно, так как позволяет 3*3*[int] отобразить в тип [3][3]int, который можно разместить на стеке и передать как знаение без аллокаций.

Из-за этой оптимизации для следующих комбинаторов 3*[int] 4*[int] и n*[int] где n нефиксирован будет сгенрировано 3 разных Go типа.

# структуры

Отображаются в структуры Go.

# маски полей

Локальные маски полей хранятся в натуральном для TL виде uint32, если какое-то поле зависит от маски полей, то кроме поля будет сгенерированы методы
SetFieldX и IsSetFieldX который ставят и проверяют соответствующий бит маски.

Маски полей-аргументы шаблона не хранятся в объектах, а передаются снаружи в методы Read, Write.

Таким образом сгенерированные типы не содержат избыточных масок полей.

# обьединения

Генерируются в структуру Go, содержащую все варианты обьединения.
На первый взгляд это неоптимально с точки зрения памяти, но на самом деле позволяет идеально переиспользовать []byte и слайсы в
каждом варианте при повторном парсинге. Это часто перекрывает эффект от того, что сами структуры занимают немного больше.

В качестве селектора варианта используется приватное поле номер конструктора.

# перечисления

Похожи на обьединения, но содержат функции MakeXXX

# Bytes-версии и работы с минимумом аллокаций

tlgen генерирует эффективный код на go, который поддерживает стиль
программирования с reuse, позволяющий значительно уменьшить число аллокаций и стоимость GC.

Если комбинатор содержит TL string, то генерируется go string, так что при каждом чтении TL будет происходить аллокация каждой строки.
С помощь опции --generateByteVersions можно попросить tlgen сгенерировать в дополнение к основным также версии типов, где вместо строк используется []byte.

При чтении соответствуюший []byte будет переиспользоваться, и если длина достаточно, то новой аллокации не будет.

Таким образом, например, если сервер читает некий TL запрос, он может иметь sync.Pool структур, брать из пула структуру, десерилизоввать, отвечать на запрос, и затем класть структуру обратно в пул.
При работе сервера все строки и другие слайсы довольно быстро перестанут аллоцироваться, и таким образо деаллоцироваться.

Нужно только понимать, что всеми слайсами в TL объекте владеет сам TL-объект, и при необходимости долговременного хранения нужно либо скопировать себе данные, либо сослаться на них, но тогда не класть структуру обратно в пул для reuse.

# метаданные и фабрика

Генерируется также пакет meta и factory.

meta содержит метаданные для всех комбинаторов, доступные по magic или имени комбинатора.

Если импортировать пакет factory, то для каждого комбинатора можно будет в runtime получить интерфейс, который позволит читать записывать и перекодировать TL-обьекты в другой формат на лету.

# JSON-представление

Все сгенерированные типы кроме методов ReadTL и WriteTL содержат также методы ReadJSON и WriteJSON.

Также WriteJSON используется в реализации интерфейса String(), так что печать TL-обьекта на экран или в лог
выводит его в каноническом формате, который можно распарсить.

Больше информации про каноническое представление JSON есть в документе TLPrimer.pdf

Если передать флаг --generateSchemaDocumentation, то сгенерируется HTML с документацией и примерами JSON для каждого комбинатора.

# RPC

Если передать флаг --generateRPCCode, то для всех TL-функций будет сгенерирова код
для реализации сервера (Handler) и клиентов (Client) в каждом пакете соответствующем TL namespace.

Этот код требует пакет RPC, который находится в opensource как часть проекта statashouse.
В дальнейшем есть планы пепеместить код RPC в проект tlgen.

# random

Если передать флаг --generateRandomCode, то у каждого сгенерированного типа появится возможность
создавать детерминистски случайный экземпляр, это важно для тестов.

5 changes: 5 additions & 0 deletions docs/tldoc.ru.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# TL (Type Language)

Формат md не поддерживает цвета, так что лучше всего читать
исходный документ в формате pdf.

Этот же файл получен автоконвертером и без цветов на схемах гораздо менее понятен, чем оригинал.

## Общие сведения

TL это язык описания данных и формат хранения данных.
Expand Down
3 changes: 1 addition & 2 deletions internal/tlast/tlgen_tlo.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ func (tl TL) GenerateTLO(version uint32) (tls.SchemaV4, error) {
}
}
var mc paramScope
left := tls.CombinatorLeft{}
args := make([]tls.Arg, 0, len(c.TemplateArguments)+len(c.Fields))
for i, ta := range c.TemplateArguments {
var tag int32
Expand Down Expand Up @@ -224,7 +223,7 @@ func (tl TL) GenerateTLO(version uint32) (tls.SchemaV4, error) {
mc.append(f.FieldName, f.FieldType.Type.String(), len(c.TemplateArguments)+i)
}
}
left = tls.CombinatorLeft0{
left := tls.CombinatorLeft0{
ArgsNum: uint32(len(args)),
Args: args,
}.AsUnion()
Expand Down
Loading
Loading