[ ](https://github.com/brightluau/bright/edit/master/docs/developer-guide/transformonomicon/configuration.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/developer-guide/transformonomicon/configuration.md "View source of this page")

# Configuration¶

This part of the documentation is currently under construction.

Transformers can register a configuration definition for Bright to provide custom rules in its configuration file. These allow a user to specify how a transformer should act, such as appending a comment to the end of a file rather than the start. For transformers that inject new nodes into the CST, it is advisable that you define a configuration.

## Setup¶

As written in [Your First Transformer](https://brightluau.dev/developer-guide/tutorials/transformer-basics/#defining-configuration), a configuration is defined like so:

    1
    2
    3
    4
    5
    6
    7

    local config = {
        some_option = {
            description = "Should do xyz",
            default = true
    type Config = bright.Config<typeof(config)>

Which maps to the following TOML:

    1
    2

    [rules.<transformer-name>]
    some_option = true

Your function will be provided a table that conforms to the newly-created `Config` type as its second argument when it's invoked:

    1
    2
    3
    4
    5
    6
    7
    8
    9

    local function transformer(cst: bright.Cst, config: Config): bright.Cst
        if config.some_option then
            print("huzzah!")
        end
    end

    return {
        bright.defineTransformer("transformer", config, transformer)

Even if the configuration isn't defined in `bright.toml`, Bright will always provide values based on your default settings. A default is **mandatory** because of this. Transformers cannot stop working because a configuration isn't provided, but the default operation should be documented.

The `description` field of your configuration is used by Bright's `config` command. This generates a transformer rule block and outputs it to the terminal, primarily to make it easier for end users to discover what configuration options your transformer has.

## Type Validation¶

If an option is of the wrong type in the configuration file, Bright will throw a runtime error stating this.

Any type is valid as an option type, as long as it can be resolved down to a singular type and not a union, intersection, or negation. If you do accidentally stumble into this, the type checker will throw an error like so:

    1

    'Config' type function errored at runtime: some_option cannot be a union

If you want to provide multiple possible values for a singular option key, you can use a table:

    1
    2
    3
    4
    5
    6
    7
    8
    9

    local config = {
        some_option = {
            description = "Should do xyz"
            default = {
                a = true,
                b = 123

And you will get a type like so:

    1
    2
    3
    4
    5
    6

    type Config = {
        read some_option: {
            a: boolean,
            b: number

Warning

By using a table type, Bright cannot check if a configuration is valid at runtime, meaning that the onus is on you to validate and throw an appropriate error.

Back to top
  *[CST]: Concrete Syntax Tree


[ ](https://github.com/brightluau/bright/edit/master/docs/changelog.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/changelog.md "View source of this page")

# Changelog¶

All notable changes to Bright will be documented on this page.

The headers are linked to their respective GitHub comparison links.

## [Unreleased](https://github.com/brightluau/bright/compare/...HEAD) 12 January, 2025¶

### Added¶

  * Bright standard libraries based on Poke.
  * CLI tool to run transformers.

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/developer-guide/poke/index.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/developer-guide/poke/index.md "View source of this page")

# Poke¶

This part of the documentation is currently under construction.

Poke (/ˈpoʊkeɪ/, like the Poké in Pokémon) is the library Bright is built upon to parse and manipulate Luau AST/CSTs.

## Bleh bleh bleh¶

Back to top
  *[AST]: Abstract Syntax Tree
  *[CSTs]: Concrete Syntax Tree


[ ](https://github.com/brightluau/bright/edit/master/docs/developer-guide/transformonomicon/index.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/developer-guide/transformonomicon/index.md "View source of this page")

# Transformonomicon¶

This part of the documentation is currently under construction.

Here be dragons, thou art forewarned.

The transformonomicon contains some loopy-land writing and confusing documentation at the moment. It will be improved over time, but for now this is what you get. Pull requests are very welcome.

If you have not yet read about [Poke](https://brightluau.dev/developer-guide/poke/), please do so first. This part of the documentation assumes that you have, and will probably be even more confusing without it.

Since this book is still being written, there's not really much to talk about on its cover page Instead, you should check out the first tutorial, [Transformer Basics](https://brightluau.dev/developer-guide/tutorials/transformer-basics/)!

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/developer-guide/bright/index.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/developer-guide/bright/index.md "View source of this page")

# Bright¶

This part of the documentation is currently under construction.

Info

This part of the documentation is for the development of Bright itself. If this is not what you are looking for, go to the [developer guide index](https://brightluau.dev/developer-guide/) to find the correct information.

## Testing¶

Code testing is done through a Lune script, split into several sub-test modules. For example, to run all tests, you run `lune run tests`, but to call just the licensing test, you run `lune run tests/license`.

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/api/std/defineTransformer.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/api/std/defineTransformer.md "View source of this page")

# `function defineTransformer`¶

[](https://brightluau.dev/badges/#version "Minimum version")[dev](https://brightluau.dev/changelog/#dev)

    1
    2
    3
    4
    5

    function defineTransformer<C>(
        name: string,
        config: C,
        func: TransformerFunction<Config<C>>
    ): Transformer<C>

Defines a transformer to be returned from the transformer module.

The `func` provided will be given a configuration object as defined by [`Config<C>`](https://brightluau.dev/api/std/Config/).

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/api/index.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/api/index.md "View source of this page")

# API Documentation¶

This part of the documentation is currently under construction.

The documentation on this part of the site pertains to the API of Bright and Poke. It is hand-written (for now), however it is kept up to date and tags are added appropriately.

## Internals¶

The internals of Bright are also on this documentation, tagged with "Internal", however they should not be used in end-user work. These are documented for developers who want to work on Bright itself and the libraries.

## Tags Reference¶

### Experimental¶

This part of the API is considered experimental, and may change or be removed at any point. This is only applied to APIs that are only available in [](https://brightluau.dev/badges/#version "Minimum version")[dev](https://brightluau.dev/changelog/#dev) versions of Bright.

### Internal¶

This part of the API is for internal use, and is only documented for ease of development. Internal APIs are not considered stable and may potentially break your transformers and/or tooling between non-major versions of Bright. They also do not have any version tag to further discourage their use.

### Yields¶

This method call yields the thread.

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/api/std/Config.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/api/std/Config.md "View source of this page")

# `type function Config`¶

[](https://brightluau.dev/badges/#version "Minimum version")[dev](https://brightluau.dev/changelog/#dev)

    1

    type function Config(userConfig)

Accepts a configuration definition object and returns a key-value pair based on the definition's default values.

See [Configuration](https://brightluau.dev/developer-guide/transformonomicon/configuration/) for more information on how to use this type.

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/get-started/index.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/get-started/index.md "View source of this page")

# Get Started¶

This part of the documentation is currently under construction.

Bright seems like your cup of tea? Try it out the instructions below!

## Installation¶

There are multiple ways of installing Bright, as detailed below.

### Rokit (Recommended)¶

If you are already using Rokit in your project, simply run `rokit add brightluau/bright`. It's that easy!

### Pesde¶

Bright is also published on pesde! Run `pesde add brightluau/bright` to install it!

## Now what?¶

Now that you're set up, check out how to [initialize your project](https://brightluau.dev/user-guide/initializing-a-project/) to start transforming your codebase into a better tomorrow. Or perhaps it's irredeemable, I don't know.

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/developer-guide/poke/why.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/developer-guide/poke/why.md "View source of this page")

# Why Poke?¶

This part of the documentation is currently under construction.

Back to top


[ ](https://github.com/brightluau/bright/edit/master/docs/developer-guide/tutorials/transformer-basics.md "Edit this page") [ ](https://github.com/brightluau/bright/raw/master/docs/developer-guide/tutorials/transformer-basics.md "View source of this page")

# Transformer Basics¶

This part of the documentation is currently under construction.

Abstract

This tutorial will cover the basics of writing a transformer. By the end of this, you will have written a skeleton of a transformer, ready to make it do something interesting.

Transformers are the core component of Bright, and are the functions executed by the CLI to modify your code.

## Writing the transformer¶

Before we do anything too complex with manipulation, let's pedal back and just get Bright to load and run _something_. This is actually quite a trivial task! Let's start out like this:

bright/transformers/someTransformer.luau

    1
    2
    3
    4
    5

    local bright = require("@bright/std") -- (1)!

    local function transformer(cst: bright.Cst): bright.Cst
        return cst
    end

  1. Bright's libraries are commonly aliased to `@bright/` for convenience and cross-compatibility (and this is recommended), but your project doesn't necessarily need to be set up this way. The CLI automatically generates a `.luaurc` file for this support if you're using [pesde](https://pesde.dev/). All libraries are accessible through a root import if necessary, so `require("path/to/bright").std` works as well.

This is the simplest possible transformer: a no-op. We'll add more to this later, of course, but for now let's break down what's going on.

`bright.Cst` is a re-export of [Poke](https://brightluau.dev/developer-guide/poke/)'s `Cst` type. A CST is like an AST, except that it includes extra information about spacing and comments, referred to as trivia. The Poke documentation contains more information about them, as well as the API for how you can manipulate them.

## Defining configuration¶

Transformers often take a configuration, referred to as the _rules_ of a transformer. As you should've spotted, we use a TOML file to define Bright's overall configuration, but this also includes the rules for transformers. For the sake of the example, let's say we want our transformer to take this sort of configuration:

bright.toml

    1
    2

    [rules.some-transformer]
    some_option = true

Regarding naming

TOML's specification doesn't dictate whether dashes or underscores should be used for naming and both are valid, however we recommend naming your transformers with dash-separated names (like `some-transformer`), and your rule keys with underscores (like `some_option`). This seems to be the common way of doing things and is also the most convenient to do in Luau.

We can define it like this in Luau:

    1
    2
    3
    4
    5
    6

    local config = {
        some_option = {
            description = "Should do xyz",
            default = true

This object defines that we have `some_option`, with a default value of `true`, and a description of... nothing of substance, but it does have one. By itself, this is all Bright needs at runtime to automatically generate a configuration object to pass to your transformer function, but the type system needs a little help. This is where [`bright.Config`](https://brightluau.dev/api/std/Config/) comes in:

    1

    type Config = bright.Config<typeof(config)>

This is a type function which takes in your config object and produces a type that looks like this:

    1
    2
    3

    type Config = {
        read some_option: boolean

As you can see, it returns a key-value pair of your options and the type of the **default value**. Options can only be of one type, so no variants here!

To accept your new configuration, update your `transformer` function to look like the following:

    1
    2
    3

    local function transformer(cst: bright.Cst, config: Config): bright.Cst
        return cst
    end

Then, you can read the configuration options just as you would expect:

    1
    2
    3
    4
    5
    6
    7

    local function transformer(cst: bright.Cst, config: Config): bright.Cst
        if config.some_option then
            print("some_option set!")
        end

        return cst
    end

There are some quirks with how configuration works, so it is advisable to read [Configuration](https://brightluau.dev/developer-guide/transformonomicon/configuration/) as you develop your transformers.

If you don't want a configuration for your transformer, then you should use [`bright.NoConfig`](https://brightluau.dev/api/std/NoConfig/). This is a simple type that is the equivalent of `type NoConfig = bright.Config<{}>`, however it is provided so that you don't need to define your own.

Usage of `NoConfig`

    1
    2
    3
    4
    5
    6
    7

    local function transformer(cst: bright.Cst, _config: bright.NoConfig): bright.Cst
        -- ...
    end

    return {
        bright.defineTransformer("some-transformer", {}, transformer),

## Registration¶

For Bright to detect your transformer, you need to define and return it from this file. This is accomplished with [`bright.defineTransformer`](https://brightluau.dev/api/std/defineTransformer/). It takes three arguments: the transformer's name, the configuration object, and the transformer function. At the end of your file, add this:

bright/transformers/someTransformer.luau

    1
    2
    3

    return {
        bright.defineTransformer("some-transformer", config, transformer),

That's it! Your transformer is now ready for use!

Tip

Because `defineTransformer` takes a name, you can register a transformer under a different name compared to its file name, or you can even register multiple transformers per file if necessary (or you want a common set of transformers). Just make sure you return them all in the table!

## Conclusion¶

You've now got a transformer that looks like this:

bright/transformers/someTransformer.luau

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    local bright = require("@bright/std")

    local config = {
        some_option = {
            description = "Should do xyz",
            default = true
    type Config = bright.Config<typeof(config)>

    local function transformer(cst: bright.Cst, config: Config): bright.Cst
        if config.some_option then
            print("some_option set!")
        end

        return cst
    end

    return {
        bright.defineTransformer("some-transformer", config, transformer),

Congratulations! You now have your first ever transformer! It only goes downhill from here, trust me...

Back to top
  *[CST]: Concrete Syntax Tree
  *[AST]: Abstract Syntax Tree


I am no longer working in Luau, therefore this project has been parked for now.

I may revive it in the future, but for now there is nothing more to see here.

# Luau Linter

A modern, extensible linter for Luau, built in Luau.

## 🚀 Quick Start

### Prerequisites
- [Lute](https://github.com/lune-org/lute) installed and available in PATH

## 🧪 Example Output

🚀 Luau Hybrid Linter - Proof of Concept
Rule: Remove unnecessary ipairs() usage
=================================================

🔍 Linting: test_files/legacy_code.luau
----------------------------------------
⚠  Found 1 issue(s):
  1. Unnecessary ipairs() call - modern Luau can iterate arrays directly
     Line 2, Column 13
     💡 Autofix available: Remove ipairs() wrapper

📊 Summary: Found 1 total issues across 1 files
🎯 Proof of concept complete! Lute-based hybrid linter is working!

### Contributing

This project is currently in proof-of-concept phase.

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.


# Luau.Page

Free custom domain for your Luau website.

1. Create a website with Luau content
2. Create a PR to add your website to `cname.luau`
3. Add the custom domain to your website


Luau.Page is currently serving **11** sites.

<https://luau.page> <https://playfab.luau.page> <https://purse.luau.page> <https://typeforge.luau.page> <https://lynx.luau.page> <https://sentry.luau.page> <https://ui-labs.luau.page> <https://hermes.luau.page> <https://satchel.luau.page> <https://rocket.luau.page> <https://react.luau.page>

Get your own custom domain for your Luau project. In just a few steps, you can have your own subdomain on luau.page.

## Create a website with Luau content

To get a custom domain, you need to create a website with Luau content. Consider hosting your website on GitHub Pages, Netlify, or Vercel.

## Create a pull request to add your domain

Once you have a website, create a pull request to add your subdomain to the [cname.luau](https://github.com/Nicell/luau.page/blob/main/cname.luau) file.

## Add the custom domain to your website

Once your pull request is merged, you need to add the custom domain to your website. This is usually done in the settings of your hosting provider. It may take anywhere from a few minutes to a day for the DNS changes to propagate.


# Luau-copyrawmetatable
An implementation of the commonly used exploit function `getrawmetatable`. It retrieves the raw metatable to the limits Luau allows.

This code is NOT intended for malicious use, purely for debugging and anticheat purposes. I, 12345koip, will NOT accept responsibility for ANY CONSEQUENCES that arise from the misuse of this code.

I am always open to suggestions and improvements! Please feel free to modify this how you please. If you want to share your changes, feel free to put it on the forum post:
https://devforum.roblox.com/t/function-getrawmetatable-written-in-pure-luau-copyrawmetatable/3614957


# rsml-luau
Generated by [Rojo](https://github.com/rojo-rbx/rojo) 7.4.4.

## Getting Started
To build the place from scratch, use:

```bash
rojo build -o "rsml-luau.rbxlx"

Next, open `rsml-luau.rbxlx` in Roblox Studio and start the Rojo server:

```bash
rojo serve

For more help, check out [the Rojo documentation](https://rojo.space/docs).


[![wally][wally-image]][wally-link]
[![AGPL-3.0 licensed][license-image]][license-link]
[![docs][docs-image]][docs-link]
[![CI][ci-image]][ci-link]

## [read the docs](https://rusty-luau.devcomp.xyz/api/)

strongly typed implementations of various rust idioms in luau.

currently, the following implementations are available:
- [Future](https://rusty-luau.devcomp.xyz/api/Future)
- [Option](https://rusty-luau.devcomp.xyz/api/Option)
- [Result](https://rusty-luau.devcomp.xyz/api/Result)

[//]: # (badges)

[wally-image]: https://img.shields.io/github/v/tag/CompeyDev/rusty-luau?label=wally&logo=lua
[wally-link]: https://wally.run/package/compeydev/rusty-luau
[docs-image]: https://github.com/CompeyDev/rusty-luau/actions/workflows/docs.yaml/badge.svg
[docs-link]: https://rusty-luau.devcomp.xyz/
[license-image]: https://img.shields.io/github/license/CompeyDev/rusty-luau
[license-link]: https://github.com/CompeyDev/rusty-luau/blob/main/LICENSE.md
[ci-image]: https://github.com/CompeyDev/rusty-luau/actions/workflows/ci.yaml/badge.svg
[ci-link]: https://github.com/CompeyDev/rusty-luau/actions/workflows/ci.yaml


# Nexus-Instance
Nexus Instance is a utility for creating custom instances
with property change events while still providing proper
typing in Luau.

## Usage
### Simple Classes
Classes with metatables are created mostly the same, except:
- `NexusInstance.ToInstance` is called before using or returning
  the class.
- The recommended type of `self` becomes `NexusInstance<Class>`.

The return type of `NexusInstance.ToInstance` is
`NexusInstanceClass<TClass, TConstructor>`, which should be
casted to. The generic types are:
- `TClass`: Type of the class without properties. Typically will be
  `typeof(MyClass)` where `MyClass` is the table of the class.
- `TConstructor`: Type of the constructor function. It should be the
  arguments of `new(...)` with the return of `NexusInstance<MyClass>`.

```luau
--!strict
local NexusInstance = require(game:GetService("ReplicatedStorage"):WaitForChild("NexusInstance"))

local TestClass = {}
TestClass.__index = TestClass

--Exported test class type and Nexus Instance version (optional).
export type TestClass = {
    TestProperty: string,
} & typeof(setmetatable({}, TestClass))
export type NexusInstanceTestClass = NexusInstance.NexusInstance<TestClass>

--Optional constructor when `new` is called.
function TestClass.__new(self: NexusInstanceTestClass, Argument: string): ()
    self.TestProperty = Argument
end

--Custom function.
function TestClass.ChangeValue(self: NexusInstanceTestClass, NewValue: string): ()
    self.TestProperty = NewValue
end

--Optional destroy function to clear resources.
--Events are cleaned internally (`Changed`, `GetPropertyChangedSignal`, and `CreateEvent` only).
--The version returned by NexusInstance.ToInstance will always have a Destroy method.
function TestClass.Destroy(self: NexusInstanceTestClass): ()
    --Clear resources.
end

--Create the class to return in the ModuleScript, or use within the script.
--The constructor (second generic type) should match inputs for `__new` without the `self`.
local ReturnedTestClass = NexusInstance.ToInstance(TestClass) :: NexusInstance.NexusInstanceClass<typeof(TestClass), (Argument: string) -> (NexusInstanceTestClass)>

--Create and destroy the type.
local TestObject = ReturnedTestClass.new("TestValue")
print(TestObject.TestProperty) --"TestValue"
TestObject:ChangeValue("NewValue")
print(TestObject.TestProperty) --"NewValue"
TestObject:Destroy()

`__new` and `Destroy` are not required and can be omitted.

```luau
--!strict
local NexusInstance = require(game:GetService("ReplicatedStorage"):WaitForChild("NexusInstance"))

local TestClass = {}
TestClass.__index = TestClass

--Exported test class type and Nexus Instance version (optional).
export type TestClass = {
    TestProperty: string?, --No constructor initializes this.
} & typeof(setmetatable({}, TestClass))
export type NexusInstanceTestClass = NexusInstance.NexusInstance<TestClass>

--Custom function.
function TestClass.ChangeValue(self: NexusInstanceTestClass, NewValue: string): ()
    self.TestProperty = NewValue
end

--Create the class to return in the ModuleScript, or use within the script.
local ReturnedTestClass = NexusInstance.ToInstance(TestClass) :: NexusInstance.NexusInstanceClass<typeof(TestClass), () -> (NexusInstanceTestClass)>

--Create and destroy the type.
local TestObject = ReturnedTestClass.new()
print(TestObject.TestProperty) --nil
TestObject:ChangeValue("NewValue")
print(TestObject.TestProperty) --"NewValue"
TestObject:Destroy()

### Inheritance
Inheritance is nearly the same as doing so with metatables, except for
the calls to `NexusInstance.ToInstance`.

```luau
--!strict
local NexusInstance = require(game:GetService("ReplicatedStorage"):WaitForChild("NexusInstance"))

--Define TestClass1 (potentially in a ModuleScript).
local TestClass1 = {}
TestClass1.__index = TestClass1

export type TestClass1 = {
    TestProperty1: string,
} & typeof(setmetatable({}, TestClass1))
export type NexusInstanceTestClass1 = NexusInstance.NexusInstance<TestClass1>

function TestClass1.__new(self: NexusInstanceTestClass1, Input: string)
    self.TestProperty1 = Input
end

function TestClass1.ChangeValue1(self: NexusInstanceTestClass1, NewValue: string): ()
    self.TestProperty1 = NewValue
end

local TestClass1NexusInstance = NexusInstance.ToInstance(TestClass1) :: NexusInstance.NexusInstanceClass<typeof(TestClass1), (Input: string) -> (NexusInstanceTestClass1)>

--Define TestClass2 (potentially in a different ModuleScript).
local TestClass2 = {}
TestClass2.__index = TestClass2
setmetatable(TestClass2, TestClass1NexusInstance) --TestClass1NexusInstance would be returned instead of TestClass1.

export type TestClass2 = {
    TestProperty2: string,
} & typeof(setmetatable({}, TestClass2)) & TestClass1
export type NexusInstanceTestClass2 = NexusInstance.NexusInstance<TestClass2>

function TestClass2.__new(self: NexusInstanceTestClass2, Input1: string, Input2: string)
    TestClass1.__new(self, Input1) --Remember to call the parent constructor!
    self.TestProperty2 = Input2
end

function TestClass2.ChangeValue2(self: NexusInstanceTestClass2, NewValue: string): ()
    self.TestProperty2 = NewValue
end

local TestClass2NexusInstance = NexusInstance.ToInstance(TestClass2) :: NexusInstance.NexusInstanceClass<typeof(TestClass2), (Input1: string, Input2: string) -> (NexusInstanceTestClass2)>

--Use the classes.
local TestObject1 = TestClass1NexusInstance.new("TestValue1")
print(TestObject1.TestProperty1) --"TestValue1"
TestObject1:ChangeValue1("NewValue1")
print(TestObject1.TestProperty1) --"NewValue1"
TestObject1:Destroy()

local TestObject2 = TestClass2NexusInstance.new("TestValue1", "TestValue2")
print(TestObject2.TestProperty1) --"TestValue1"
print(TestObject2.TestProperty2) --"TestValue2"
TestObject2:ChangeValue1("NewValue1")
TestObject2:ChangeValue2("NewValue2")
print(TestObject2.TestProperty1) --"NewValue1"
print(TestObject2.TestProperty2) --"NewValue2"
TestObject2:Destroy()

### Metatable Passthrough
Classes can define some metatable methods, which will be passed
through. `__index` and `__newindex` are not supported for this.

```luau
--!strict
local NexusInstance = require(game:GetService("ReplicatedStorage"):WaitForChild("NexusInstance"))

local TestClass = {}
TestClass.__index = TestClass

--Exported test class type and Nexus Instance version (optional).
export type TestClass = typeof(setmetatable({}, TestClass))
export type NexusInstanceTestClass = NexusInstance.NexusInstance<TestClass>

--__tostring metatable method.
function TestClass.__tostring(self: NexusInstanceTestClass): ()
    return "TestClass"
end

--Create the class to return in the ModuleScript, or use within the script.
local ReturnedTestClass = NexusInstance.ToInstance(TestClass) :: NexusInstance.NexusInstanceClass<typeof(TestClass), () -> (NexusInstanceTestClass)>

--Create and destroy the type.
local TestObject = ReturnedTestClass.new()
print(tostring(TestObject)) --"TestClass"
TestObject:Destroy()

### Property Changes
Similar to normal Roblox `Instance`s, there is a `Changed` event
that is fired when any property changes, and `GetPropertyChangedSignal`
to listen to a specific property changing.

```luau
TestObject.Changed:Connect(function(PropertyName)
    print(`Property {PropertyName} changed.`)
end)
TestObject:GetPropertyChangedSignal("TestProperty"):Connect(function()
    print("PropertyName changed.")
end)

Changed events can be ignored using `HidePropertyChanges`.
`HideNextPropertyChange` can be used to only hide the next property change.

```luau
TestObject.Changed:Connect(function(PropertyName)
    print(`Property {PropertyName} changed.`)
end)
TestObject:GetPropertyChangedSignal("TestProperty"):Connect(function()
    print("PropertyName changed.")
end)

TestObject:HidePropertyChanges("TestProperty") --This makes it so changed events never invokes for TestProperty.
TestObject:HideNextPropertyChange("TestProperty") --This makes it so only the next changed event doesn't get invoked for TestProperty.

`OnAnyPropertyChanged` and `OnPropertyChanged` also exist. Unlike
the events, they will immediately invoke after a property change
(as opposed to waiting on deferred events). They do not respect
hidden changed events and will always be invoked.

```luau
TestObject:OnAnyPropertyChanged(function(PropertyName, Value)
    print(`Property {PropertyName} changed to {Value}.`)
end)
TestObject:OnPropertyChanged("TestProperty", function(Value)
    print(`TestProperty changed to {Value}.`)
end)

### Property Transformers
When a property is set, it is able to be transformed before
being stored and invoked with changed events. Generic transforms
will always run before property-speicifc ones.

```luau
TestObject:AddGenericPropertyTransform(function(Index, Value)
    return `{Value}_{Index}_1`
end)
TestObject:OnAnyPropertyChanged("TestProperty", function(Value)
    return `{Value}_2`
end)

TestObject.TestProperty = "NewValue"
print(TestObject.TestProperty) --"NewValue_TestProperty_1_2"

### Custom Events
`TypedEvent` exists for custom events. Compared to `BindableEvent`:
- `TypedEvent`s have typing for the arguments.
- Arguments that are passed retain their original table/function
  references, instead of being encoded away.

`CreateEvent` is always recommended unless being used outside
of an instance, since `CreateEvent` will handle disconnecting
the event when the instance is destroyed.

```luau
--!strict
local NexusInstance = require(game:GetService("ReplicatedStorage"):WaitForChild("NexusInstance"))

local TestClass = {}
TestClass.__index = TestClass

--Exported test class type and Nexus Instance version (optional).
export type TestClass = {
    TestEvent: NexusInstance.TypedEvent<string>,
} & typeof(setmetatable({}, TestClass))
export type NexusInstanceTestClass = NexusInstance.NexusInstance<TestClass>

--Optional constructor when `new` is called.
function TestClass.__new(self: NexusInstanceTestClass): ()
    self.TestEvent = self:CreateEvent() :: NexusInstance.TypedEvent<string>
end

--Create the class to return in the ModuleScript, or use within the script.
local ReturnedTestClass = NexusInstance.ToInstance(TestClass) :: NexusInstance.NexusInstanceClass<typeof(TestClass), () -> (NexusInstanceTestClass)>

--Create and destroy the type.
local TestObject = ReturnedTestClass.new()
TestObject.TestEvent:Connect(function(Message)
    print(Message)
end)
TestObject.TestEvent:Fire("Test message") --Prints "Test message"
TestObject:Destroy() --Disconnects TestEvent.

## Contributing
Both issues and pull requests are accepted for this project.

## License
Nexus Instance is available under the terms of the MIT
License. See [LICENSE](LICENSE) for details.


# luau-hangul
한국어 | [English](https://github.com/Word30210/luau-hangul/blob/main/README-en_us.md)

luau-hangul은 [toss](https://github.com/toss)의 [es-hangul](https://github.com/toss/es-hangul)을 Luau로 포팅하여, Luau로 한글을 쉽게 처리할 수 있게 하는 라이브러리입니다.

## 사용 예시
문자열 초성화, 조사 붙이기와 같은 한글 작업을 간단히 할 수 있습니다.

```lua
local hangul = require(path.to.luau_hangul)
local getChoseong = hangul.core.getChoseong

local searchWord = "라면"
local userInput = "ㄹㅁ"

local result = getChoseong.GetChoseong(searchWord) -- ㄹㅁ

-- 검색어의 초성과 사용자 입력 초성이 일치하는지 확인
if result == userInput then
    something()
end

```lua
local hangul = require(path.to.luau_hangul)
local josa = hangul.core.josa

local word1 = "사과"
local sentence1 = josa.josa(word1, "을/를") .. " 먹었습니다."
print(sentence1) -- "사과를 먹었습니다."

local word2 = "바나나"
local sentence2 = josa.josa(word2, "이/가") .. " 맛있습니다."
print(sentence2) -- "바나나가 맛있습니다."

## 설치하기
**만약 pesde를 사용하고 있다면,**
```bash
pesde init # pesde 초기화를 하지 않았다면
pesde add word30210/luau-hangul
pesde install

**만약 wally를 사용하고 있다면,**
안타깝지만 아직 luau-hangul은 wally에 올라와 있지 않습니다.

**만약 그냥 로블록스 스튜디오를 사용하고 있다면,**
[Github Releases](https://github.com/Word30210/luau-hangul/releases)에서 최신 버전을 다운로드 해 주세요.

## 기여하기
모든 분들의 기여를 환영합니다. 하지만,
luau-hangul은 es-hangul의 모든 api를 포팅하는것을 목표로 하고 있습니다.
따라서, es-hangul의 api를 포팅하는것 이외의 기능추가 PR은 받지 않습니다.

## Todo
- new solver에서도 동작하도록 수정
- API 문서화

# Special Thanks
- [@toss](https://github.com/toss) for inspiration.


`protoc-gen-luau` generates strictly typed Luau files from [Protobuf](https://protobuf.dev/) files.

To use, clone the repo and run `cargo install`. When you run `protoc`, add `--luau_out=path/to/protos`. For example, to export protos in `protos/` to `src/LuauProtos/`...

protoc -Iprotos --luau_out=src/LuauProtos

## Options
- Add `--luau_opt=roblox_imports=true` to indicate you are in a Roblox environment. This currently replaces `require`s from string requires to instance based requires. I'm not actually sure this is necessary anymore though.

- `--luau_opt=field_name_case=snake|camel` — Control Luau field names casing. If no option is passed, the default behavior is to keep the field name as written in the .proto file.

## API

### Messages
Suppose we have the following message:
```protobuf
message Pair {
    double x = 1;
    double y = 2;
The exported script will have the following:
- Exported type `Pair` representing the Pair class
- A `Pair` class with:
    - `Pair.new(partialFields): Pair`
        - `partialFields` in this case would be `{ x: number?, y: number? }`. Anything not specified will be defaulted as per Protobuf's rules.
    - `Pair:encode(): buffer`
        - Returns a buffer representing the serialized Protobuf.
    - `Pair.decode(input: buffer): Pair`
        - Deserializes a serialized Protobuf.
    - `Pair:jsonEncode(): { [string]: any }`
        - Returns a JSON encoded representation of the message as per Protobuf's rules.
    - `Pair.jsonDecode(input: { [string]: any }): Pair`
        - Deserializes a JSON encoded representation of the message as per Protobuf's rules.
    - `Pair.descriptor: proto.Descriptor`
        - A runtime representation of what the type is--just a struct with `{ name: string, fullName: string }`.

### Enums
If we have the following:
```protobuf
enum Kind {
    A = 0,
    B = 1,
    C = 2,
The exported script will export a type `Kind` that is a union string of all the options, as well as `number` for when it is unspecified. In this case: `"A" | "B" | "C" | number`

### Any
`Any` is supported, though these docs are not ready yet.


# Protocol Buffers

Protocol Buffers are language-neutral, platform-neutral extensible mechanisms for serializing structured data.

## What Are Protocol Buffers?

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

## Pick Your Favorite Language

Protocol buffers support generated code in C++, C#, Dart, Go, Java, Kotlin, Objective-C, Python, Rust, and Ruby. With proto3, you can also work with PHP.

## Example Implementation

    edition = "2024";

    message Person {
      string name = 1;
      int32 id = 2;
      string email = 3;

**Figure 1.** A proto definition.

    // Java code
    Person john = Person.newBuilder()
        .setId(1234)
        .setName("John Doe")
        .setEmail("jdoe@example.com")
        .build();
    output = new FileOutputStream(args[0]);
    john.writeTo(output);

**Figure 2.** Using a generated class to persist data.

    // C++ code
    Person john;
    fstream input(argv[1],
        ios::in | ios::binary);
    john.ParseFromIstream(&input);
    id = john.id();
    name = john.name();
    email = john.email();

**Figure 3.** Using a generated class to parse persisted data.

## How Do I Start?

  1. [Download and install](https://github.com/protocolbuffers/protobuf#protobuf-compiler-installation) the protocol buffer compiler.
  2. Read the [overview](https://protobuf.dev/overview).
  3. Try the [tutorial](https://protobuf.dev/getting-started) for your chosen language.


# Overview

Protocol Buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.

It’s like JSON, except it’s smaller and faster, and it generates native language bindings. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

Protocol buffers are a combination of the definition language (created in `.proto` files), the code that the proto compiler generates to interface with data, language-specific runtime libraries, the serialization format for data that is written to a file (or sent across a network connection), and the serialized data.

## What Problems do Protocol Buffers Solve?

Protocol buffers provide a serialization format for packets of typed, structured data that are up to a few megabytes in size. The format is suitable for both ephemeral network traffic and long-term data storage. Protocol buffers can be extended with new information without invalidating existing data or requiring code to be updated.

Protocol buffers are the most commonly-used data format at Google. They are used extensively in inter-server communications as well as for archival storage of data on disk. Protocol buffer _messages_ and _services_ are described by engineer-authored `.proto` files. The following shows an example `message`:

    edition = "2023";

    message Person {
      string name = 1;
      int32 id = 2;
      string email = 3;

The proto compiler is invoked at build time on `.proto` files to generate code in various programming languages (covered in Cross-language Compatibility later in this topic) to manipulate the corresponding protocol buffer. Each generated class contains simple accessors for each field and methods to serialize and parse the whole structure to and from raw bytes. The following shows you an example that uses those generated methods:

    Person john = Person.newBuilder()
        .setId(1234)
        .setName("John Doe")
        .setEmail("jdoe@example.com")
        .build();
    output = new FileOutputStream(args[0]);
    john.writeTo(output);

Because protocol buffers are used extensively across all manner of services at Google and data within them may persist for some time, maintaining backwards compatibility is crucial. Protocol buffers allow for the seamless support of changes, including the addition of new fields and the deletion of existing fields, to any protocol buffer without breaking existing services. For more on this topic, see Updating Proto Definitions Without Updating Code, later in this topic.

## What are the Benefits of Using Protocol Buffers?

Protocol buffers are ideal for any situation in which you need to serialize structured, record-like, typed data in a language-neutral, platform-neutral, extensible manner. They are most often used for defining communications protocols (together with gRPC) and for data storage.

Some of the advantages of using protocol buffers include:

  * Compact data storage
  * Fast parsing
  * Availability in many programming languages
  * Optimized functionality through automatically-generated classes

### Cross-language Compatibility

The same messages can be read by code written in any supported programming language. You can have a Java program on one platform capture data from one software system, serialize it based on a `.proto` definition, and then extract specific values from that serialized data in a separate Python application running on another platform.

The following languages are supported directly in the protocol buffers compiler, protoc:

  * [C++](https://protobuf.dev/reference/cpp/cpp-generated#invocation)
  * [C#](https://protobuf.dev/reference/csharp/csharp-generated#invocation)
  * [Java](https://protobuf.dev/reference/java/java-generated#invocation)
  * [Kotlin](https://protobuf.dev/reference/kotlin/kotlin-generated#invocation)
  * [Objective-C](https://protobuf.dev/reference/objective-c/objective-c-generated#invocation)
  * [PHP](https://protobuf.dev/reference/php/php-generated#invocation)
  * [Python](https://protobuf.dev/reference/python/python-generated#invocation)
  * [Ruby](https://protobuf.dev/reference/ruby/ruby-generated#invocation)

The following languages are supported by Google, but the projects’ source code resides in GitHub repositories. The protoc compiler uses plugins for these languages:

  * [Dart](https://github.com/google/protobuf.dart)
  * [Go](https://github.com/protocolbuffers/protobuf-go)

Additional languages are not directly supported by Google, but rather by other GitHub projects. These languages are covered in [Third-Party Add-ons for Protocol Buffers](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md).

### Cross-project Support

You can use protocol buffers across projects by defining `message` types in `.proto` files that reside outside of a specific project’s code base. If you’re defining `message` types or enums that you anticipate will be widely used outside of your immediate team, you can put them in their own file with no dependencies.

A couple of examples of proto definitions widely-used within Google are [`timestamp.proto`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto) and [`status.proto`](https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto).

### Updating Proto Definitions Without Updating Code

It’s standard for software products to be backward compatible, but it is less common for them to be forward compatible. As long as you follow some [simple practices](https://protobuf.dev/programming-guides/proto3#updating) when updating `.proto` definitions, old code will read new messages without issues, ignoring any newly added fields. To the old code, fields that were deleted will have their default value, and deleted repeated fields will be empty. For information on what “repeated” fields are, see Protocol Buffers Definition Syntax later in this topic.

New code will also transparently read old messages. New fields will not be present in old messages; in these cases protocol buffers provide a reasonable default value.

### When are Protocol Buffers not a Good Fit?

Protocol buffers do not fit all data. In particular:

  * Protocol buffers tend to assume that entire messages can be loaded into memory at once and are not larger than an object graph. For data that exceeds a few megabytes, consider a different solution; when working with larger data, you may effectively end up with several copies of the data due to serialized copies, which can cause surprising spikes in memory usage.
  * When protocol buffers are serialized, the same data can have many different binary serializations. You cannot compare two messages for equality without fully parsing them.
  * Messages are not compressed. While messages can be zipped or gzipped like any other file, special-purpose compression algorithms like the ones used by JPEG and PNG will produce much smaller files for data of the appropriate type.
  * Protocol buffer messages are less than maximally efficient in both size and speed for many scientific and engineering uses that involve large, multi-dimensional arrays of floating point numbers. For these applications, [FITS](https://en.wikipedia.org/wiki/FITS) and similar formats have less overhead.
  * Protocol buffers are not well supported in non-object-oriented languages popular in scientific computing, such as Fortran and IDL.
  * Protocol buffer messages don’t inherently self-describe their data, but they have a fully reflective schema that you can use to implement self-description. That is, you cannot fully interpret one without access to its corresponding `.proto` file.
  * Protocol buffers are not a formal standard of any organization. This makes them unsuitable for use in environments with legal or other requirements to build on top of standards.

## Who Uses Protocol Buffers?

Many projects use protocol buffers, including the following:

  * [gRPC](https://grpc.io)
  * [Google Cloud](https://cloud.google.com)
  * [Envoy Proxy](https://www.envoyproxy.io)

## How do Protocol Buffers Work?

The following diagram shows how you use protocol buffers to work with your data.

**Figure 1. Protocol buffers workflow**

The code generated by protocol buffers provides utility methods to retrieve data from files and streams, extract individual values from the data, check if data exists, serialize data back to a file or stream, and other useful functions.

The following code samples show you an example of this flow in Java. As shown earlier, this is a `.proto` definition:

    message Person {
      string name = 1;
      int32 id = 2;
      string email = 3;

Compiling this `.proto` file creates a `Builder` class that you can use to create new instances, as in the following Java code:

    Person john = Person.newBuilder()
        .setId(1234)
        .setName("John Doe")
        .setEmail("jdoe@example.com")
        .build();
    output = new FileOutputStream(args[0]);
    john.writeTo(output);

You can then deserialize data using the methods protocol buffers creates in other languages, like C++:

    Person john;
    fstream input(argv[1], ios::in | ios::binary);
    john.ParseFromIstream(&input);
    int id = john.id();
    std::string name = john.name();
    std::string email = john.email();

## Protocol Buffers Definition Syntax

When defining `.proto` files, you can specify cardinality (singular or repeated). In proto2 and proto3, you can also specify if the field is optional. In proto3, setting a field to optional [changes it from implicit presence to explicit presence](https://protobuf.dev/programming-guides/field_presence).

After setting the cardinality of a field, you specify the data type. Protocol buffers support the usual primitive data types, such as integers, booleans, and floats. For the full list, see [Scalar Value Types](https://protobuf.dev/programming-guides/proto3#scalar).

A field can also be of:

  * A `message` type, so that you can nest parts of the definition, such as for repeating sets of data.
  * An `enum` type, so you can specify a set of values to choose from.
  * A `oneof` type, which you can use when a message has many optional fields and at most one field will be set at the same time.
  * A `map` type, to add key-value pairs to your definition.

Messages can allow **extensions** to define fields outside of the message, itself. For example, the protobuf library’s internal message schema allows extensions for custom, usage-specific options.

For more information about the options available, see the language guide for [proto2](https://protobuf.dev/programming-guides/proto2), [proto3](https://protobuf.dev/programming-guides/proto3), or [edition 2023](https://protobuf.dev/programming-guides/editions).

After setting cardinality and data type, you choose a name for the field. There are some things to keep in mind when setting field names:

  * It can sometimes be difficult, or even impossible, to change field names after they’ve been used in production.
  * Field names cannot contain dashes. For more on field name syntax, see [Message and Field Names](https://protobuf.dev/programming-guides/style#message-field-names).
  * Use pluralized names for repeated fields.

After assigning a name to the field, you assign a field number. Field numbers cannot be repurposed or reused. If you delete a field, you should reserve its field number to prevent someone from accidentally reusing the number.

## Additional Data Type Support

Protocol buffers support many scalar value types, including integers that use both variable-length encoding and fixed sizes. You can also create your own composite data types by defining messages that are, themselves, data types that you can assign to a field. In addition to the simple and composite value types, several [common types](https://protobuf.dev/best-practices/dos-donts#common) are published.

## History

To read about the history of the protocol buffers project, see [History of Protocol Buffers](https://protobuf.dev/history).

## Protocol Buffers Open Source Philosophy

Protocol buffers were open sourced in 2008 as a way to provide developers outside of Google with the same benefits that we derive from them internally. We support the open source community through regular updates to the language as we make those changes to support our internal requirements. While we accept select pull requests from external developers, we cannot always prioritize feature requests and bug fixes that don’t conform to Google’s specific needs.

## Developer Community

To be alerted to upcoming changes in Protocol Buffers and to connect with protobuf developers and users, [join the Google Group](https://groups.google.com/g/protobuf).

## Additional Resources

  * [Protocol Buffers GitHub](https://github.com/protocolbuffers/protobuf/)
    * [Tutorials](https://protobuf.dev/getting-started/)


# Application Note: Field Presence

Explains the various presence-tracking disciplines for protobuf fields. It also explains the behavior of explicit presence-tracking for singular proto3 fields with basic types.

## Background

 _Field presence_ is the notion of whether a protobuf field has a value. There are two different manifestations of presence for protobufs: _implicit presence_ , where the generated message API stores field values (only), and _explicit presence_ , where the API also stores whether or not a field has been set.

#### Note

We recommend always adding the `optional` label for proto3 basic types. This provides a smoother path to editions, which uses explicit presence by default.

### Presence Disciplines

 _Presence disciplines_ define the semantics for translating between the _API representation_ and the _serialized representation_. The _implicit presence_ discipline relies upon the field value itself to make decisions at (de)serialization time, while the _explicit presence_ discipline relies upon the explicit tracking state instead.

### Presence in _Tag-value stream_ (Wire Format) Serialization

The wire format is a stream of tagged, _self-delimiting_ values. By definition, the wire format represents a sequence of _present_ values. In other words, every value found within a serialization represents a _present_ field; furthermore, the serialization contains no information about not-present values.

The generated API for a proto message includes (de)serialization definitions which translate between API types and a stream of definitionally _present_ (tag, value) pairs. This translation is designed to be forward- and backward-compatible across changes to the message definition; however, this compatibility introduces some (perhaps surprising) considerations when deserializing wire-formatted messages:

  * When serializing, fields with _implicit presence_ are not serialized if they contain their default value.
    * For numeric types, the default is 0.
    * For enums, the default is the zero-valued enumerator.
    * For strings, bytes, and repeated fields, the default is the zero-length value.
  * “Empty” length-delimited values (such as empty strings) can be validly represented in serialized values: the field is “present,” in the sense that it appears in the wire format. However, if the generated API does not track presence, then these values may not be re-serialized; i.e., the empty field may be “not present” after a serialization round-trip.
  * When deserializing, duplicate field values may be handled in different ways depending on the field definition.
    * Duplicate `repeated` fields are typically appended to the field’s API representation. (Note that serializing a _packed_ repeated field produces only one, length-delimited value in the tag stream.)
    * Duplicate `optional` field values follow the rule that “the last one wins.”
  * `oneof` fields expose the API-level invariant that only one field is set at a time. However, the wire format may include multiple (tag, value) pairs which notionally belong to the `oneof`. Similar to `optional` fields, the generated API follows the “last one wins” rule.
  * Out-of-range values are not returned for enum fields in generated proto2 APIs. However, out-of-range values may be stored as _unknown fields_ in the API, even though the wire-format tag was recognized.

### Presence in _Named-field Mapping_ Formats

Protobufs can be represented in human-readable, textual forms. Two notable formats are TextFormat (the output format produced by generated message `DebugString` methods) and JSON.

These formats have correctness requirements of their own, and are generally stricter than _tagged-value stream_ formats. However, TextFormat more closely mimics the semantics of the wire format, and does, in certain cases, provide similar semantics (for example, appending repeated name-value mappings to a repeated field). In particular, similar to the wire format, TextFormat only includes fields which are present.

JSON is a much stricter format, however, and cannot validly represent some semantics of the wire format or TextFormat.

  * Notably, JSON _elements_ are semantically unordered, and each member must have a unique name. This is different from TextFormat rules for repeated fields.
  * JSON may include fields that are “not present,” unlike the _implicit presence_ discipline for other formats:
    * JSON defines a `null` value, which may be used to represent a _defined but not-present field_.
    * Repeated field values may be included in the formatted output, even if they are equal to the default (an empty list).
  * Because JSON elements are unordered, there is no way to unambiguously interpret the “last one wins” rule.
    * In most cases, this is fine: JSON elements must have unique names: repeated field values are not valid JSON, so they do not need to be resolved as they are for TextFormat.
    * However, this means that it may not be possible to interpret `oneof` fields unambiguously: if multiple cases are present, they are unordered.

In theory, JSON _can_ represent presence in a semantic-preserving fashion. In practice, however, presence correctness can vary depending upon implementation choices, especially if JSON was chosen as a means to interoperate with clients not using protobufs.

### Presence in Proto2 APIs

This table outlines whether presence is tracked for fields in proto2 APIs (both for generated APIs and using dynamic reflection):

Field type| Explicit Presence
Singular numeric (integer or floating point)| ✔
Singular enum| ✔
Singular string or bytes| ✔
Singular message| ✔
Repeated|
Oneofs| ✔
Maps|

Singular fields (of all types) track presence explicitly in the generated API. The generated message interface includes methods to query presence of fields. For example, the field `foo` has a corresponding `has_foo` method. (The specific name follows the same language-specific naming convention as the field accessors.) These methods are sometimes referred to as “hazzers” within the protobuf implementation.

Similar to singular fields, `oneof` fields explicitly track which one of the members, if any, contains a value. For example, consider this example `oneof`:

    oneof foo {
      int32 a = 1;
      float b = 2;

Depending on the target language, the generated API would generally include several methods:

  * A hazzer for the oneof: `has_foo`
  * A _oneof case_ method: `foo`
  * Hazzers for the members: `has_a`, `has_b`
  * Getters for the members: `a`, `b`

Repeated fields and maps do not track presence: there is no distinction between an _empty_ and a _not-present_ repeated field.

### Presence in Proto3 APIs

This table outlines whether presence is tracked for fields in proto3 APIs (both for generated APIs and using dynamic reflection):

Field type| `optional`| Explicit Presence
---|---|---
Singular numeric (integer or floating point)| No|
Singular numeric (integer or floating point)| Yes| ✔
Singular enum| No|
Singular enum| Yes| ✔
Singular string or bytes| No|
Singular string or bytes| Yes| ✔
Singular message| No| ✔
Singular message| Yes| ✔
Repeated| N/A|
Oneofs| N/A| ✔
Maps| N/A|

Similar to proto2 APIs, proto3 does not track presence explicitly for repeated fields. Without the `optional` label, proto3 APIs do not track presence for basic types (numeric, string, bytes, and enums), either. Oneof fields affirmatively expose presence, although the same set of hazzer methods may not generated as in proto2 APIs.

This default behavior of not tracking presence without the `optional` label is different from the proto2 behavior. We recommend using the `optional` label with proto3 unless you have a specific reason not to.

Under the _implicit presence_ discipline, the default value is synonymous with “not present” for purposes of serialization. To notionally “clear” a field (so it won’t be serialized), an API user would set it to the default value.

The default value for enum-typed fields under _implicit presence_ is the corresponding 0-valued enumerator. Under proto3 syntax rules, all enum types are required to have an enumerator value which maps to 0. By convention, this is an `UNKNOWN` or similarly-named enumerator. If the zero value is notionally outside the domain of valid values for the application, this behavior can be thought of as tantamount to _explicit presence_.

### Presence in Editions APIs

This table outlines whether presence is tracked for fields in editions APIs (both for generated APIs and using dynamic reflection):

Field type| Explicit Presence
Singular numeric (integer or floating point)| ✔
Singular enum| ✔
Singular string or bytes| ✔
Singular message†| ✔
Repeated|
Oneofs†| ✔
Maps|

† Messages and oneofs have never had implicit presence, and editions doesn’t allow you to set `field_presence = IMPLICIT`.

Editions-based APIs track field presence explicitly, similarly to proto2, unless `features.field_presence` is set to `IMPLICIT`. Similar to proto2 APIs, editions-based APIs do not track presence explicitly for repeated fields.

## Semantic Differences

The _implicit presence_ serialization discipline results in visible differences from the _explicit presence_ tracking discipline, when the default value is set. For a singular field with numeric, enum, or string type:

  * _Implicit presence_ discipline:
    * Default values are not serialized.
    * Default values are _not_ merged-from.
    * To “clear” a field, it is set to its default value.
    * The default value may mean:
      * the field was explicitly set to its default value, which is valid in the application-specific domain of values;
      * the field was notionally “cleared” by setting its default; or
      * the field was never set.
    * `has_` methods are not generated (but see note after this list)
  * _Explicit presence_ discipline:
    * Explicitly set values are always serialized, including default values.
    * Un-set fields are never merged-from.
    * Explicitly set fields – including default values – _are_ merged-from.
    * A generated `has_foo` method indicates whether or not the field `foo` has been set (and not cleared).
    * A generated `clear_foo` method must be used to clear (i.e., un-set) the value.

#### Note

`Has_` methods are not generated for implicit members in most cases. The exception to this behavior is Dart, which generates `has_` methods with proto3 proto schema files.

### Considerations for Merging

Under the _implicit presence_ rules, it is effectively impossible for a target field to merge-from its default value (using the protobuf’s API merging functions). This is because default values are skipped, similar to the _implicit presence_ serialization discipline. Merging only updates the target (merged-to) message using the non-skipped values from the update (merged-from) message.

The difference in merging behavior has further implications for protocols which rely on partial “patch” updates. If field presence is not tracked, then an update patch alone cannot represent an update to the default value, because only non-default values are merged-from.

Updating to set a default value in this case requires some external mechanism, such as `FieldMask`. However, if presence _is_ tracked, then all explicitly-set values – even default values – will be merged into the target.

### Considerations for change-compatibility

Changing a field between _explicit presence_ and _implicit presence_ is a binary-compatible change for serialized values in wire format. However, the serialized representation of the message may differ, depending on which version of the message definition was used for serialization. Specifically, when a “sender” explicitly sets a field to its default value:

  * The serialized value following _implicit presence_ discipline does not contain the default value, even though it was explicitly set.
  * The serialized value following _explicit presence_ discipline contains every “present” field, even if it contains the default value.

This change may or may not be safe, depending on the application’s semantics. For example, consider two clients with different versions of a message definition.

Client A uses this definition of the message, which follows the _explicit presence_ serialization discipline for field `foo`:

    syntax = "proto3";
    message Msg {
      optional int32 foo = 1;

Client B uses a definition of the same message, except that it follows the _no presence_ discipline:

    syntax = "proto3";
    message Msg {
      int32 foo = 1;

Now, consider a scenario where client A observes `foo`’s presence as the clients repeatedly exchange the “same” message by deserializing and reserializing:

    // Client A:
    Msg m_a;
    m_a.set_foo(1);                  // non-default value
    assert(m_a.has_foo());           // OK
    Send(m_a.SerializeAsString());   // to client B

    // Client B:
    Msg m_b;
    m_b.ParseFromString(Receive());  // from client A
    assert(m_b.foo() == 1);          // OK
    Send(m_b.SerializeAsString());   // to client A

    // Client A:
    m_a.ParseFromString(Receive());  // from client B
    assert(m_a.foo() == 1);          // OK
    assert(m_a.has_foo());           // OK
    m_a.set_foo(0);                  // default value
    Send(m_a.SerializeAsString());   // to client B

    // Client B:
    Msg m_b;
    m_b.ParseFromString(Receive());  // from client A
    assert(m_b.foo() == 0);          // OK
    Send(m_b.SerializeAsString());   // to client A

    // Client A:
    m_a.ParseFromString(Receive());  // from client B
    assert(m_a.foo() == 0);          // OK
    assert(m_a.has_foo());           // FAIL

If client A depends on _explicit presence_ for `foo`, then a “round trip” through client B will be lossy from the perspective of client A. In the example, this is not a safe change: client A requires (by `assert`) that the field is present; even without any modifications through the API, that requirement fails in a value- and peer-dependent case.

## How to Enable _Explicit Presence_ in Proto3

These are the general steps to use field tracking support for proto3:

  1. Add an `optional` field to a `.proto` file.
  2. Run `protoc` (at least v3.15, or v3.12 using `--experimental_allow_proto3_optional` flag).
  3. Use the generated “hazzer” methods and “clear” methods in application code, instead of comparing or setting default values.

### `.proto` File Changes

This is an example of a proto3 message with fields which follow both _no presence_ and _explicit presence_ semantics:

    syntax = "proto3";
    package example;

    message MyMessage {
      // implicit presence:
      int32 not_tracked = 1;

      // Explicit presence:
      optional int32 tracked = 2;

### `protoc` Invocation

Presence tracking for proto3 messages is enabled by default [since v3.15.0](https://github.com/protocolbuffers/protobuf/releases/tag/v3.15.0) release, formerly up until [v3.12.0](https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.0) the `--experimental_allow_proto3_optional` flag was required when using presence tracking with protoc.

### Using the Generated Code

The generated code for proto3 fields with _explicit presence_ (the `optional` label) will be the same as it would be in a proto2 file.

This is the definition used in the “implicit presence” examples below:

    syntax = "proto3";
    package example;
    message Msg {
      int32 foo = 1;

This is the definition used in the “explicit presence” examples below:

    syntax = "proto3";
    package example;
    message Msg {
      optional int32 foo = 1;

In the examples, a function `GetProto` constructs and returns a message of type `Msg` with unspecified contents.

#### C++ Example

Implicit presence:

    Msg m = GetProto();
    if (m.foo() != 0) {
      // "Clear" the field:
      m.set_foo(0);
    } else {
      // Default value: field may not have been present.
      m.set_foo(1);

Explicit presence:

    Msg m = GetProto();
    if (m.has_foo()) {
      // Clear the field:
      m.clear_foo();
    } else {
      // Field is not present, so set it.
      m.set_foo(1);

#### C# Example

Implicit presence:

    var m = GetProto();
    if (m.Foo != 0) {
      // "Clear" the field:
      m.Foo = 0;
    } else {
      // Default value: field may not have been present.
      m.Foo = 1;

Explicit presence:

    var m = GetProto();
    if (m.HasFoo) {
      // Clear the field:
      m.ClearFoo();
    } else {
      // Field is not present, so set it.
      m.Foo = 1;

#### Go Example

Implicit presence:

    m := GetProto()
    if m.Foo != 0 {
      // "Clear" the field:
      m.Foo = 0
    } else {
      // Default value: field may not have been present.
      m.Foo = 1

Explicit presence:

    m := GetProto()
    if m.Foo != nil {
      // Clear the field:
      m.Foo = nil
    } else {
      // Field is not present, so set it.
      m.Foo = proto.Int32(1)

#### Java Example

These examples use a `Builder` to demonstrate clearing. Simply checking presence and getting values from a `Builder` follows the same API as the message type.

Implicit presence:

    Msg.Builder m = GetProto().toBuilder();
    if (m.getFoo() != 0) {
      // "Clear" the field:
      m.setFoo(0);
    } else {
      // Default value: field may not have been present.
      m.setFoo(1);

Explicit presence:

    Msg.Builder m = GetProto().toBuilder();
    if (m.hasFoo()) {
      // Clear the field:
      m.clearFoo()
    } else {
      // Field is not present, so set it.
      m.setFoo(1);

#### Python Example

Implicit presence:

    m = example.Msg()
    if m.foo != 0:
      # "Clear" the field:
      m.foo = 0
    else:
      # Default value: field may not have been present.
      m.foo = 1

Explicit presence:

    m = example.Msg()
    if m.HasField('foo'):
      # Clear the field:
      m.ClearField('foo')
    else:
      # Field is not present, so set it.
      m.foo = 1

#### Ruby Example

Implicit presence:

    m = Msg.new
    if m.foo != 0
      # "Clear" the field:
      m.foo = 0
    else
      # Default value: field may not have been present.
      m.foo = 1
    end

Explicit presence:

    m = Msg.new
    if m.has_foo?
      # Clear the field:
      m.clear_foo
    else
      # Field is not present, so set it.
      m.foo = 1
    end

#### Javascript Example

Implicit presence:

    var m = new Msg();
    if (m.getFoo() != 0) {
      // "Clear" the field:
      m.setFoo(0);
    } else {
      // Default value: field may not have been present.
      m.setFoo(1);

Explicit presence:

    var m = new Msg();
    if (m.hasFoo()) {
      // Clear the field:
      m.clearFoo()
    } else {
      // Field is not present, so set it.
      m.setFoo(1);

#### Objective-C Example

Implicit presence:

    Msg *m = [Msg message];
    if (m.foo != 0) {
      // "Clear" the field:
      m.foo = 0;
    } else {
      // Default value: field may not have been present.
      m.foo = 1;

Explicit presence:

    Msg *m = [Msg message];
    if ([m hasFoo]) {
      // Clear the field:
      [m clearFoo];
    } else {
      // Field is not present, so set it.
      m.foo = 1;

## Cheat sheet

**Proto2:**

Is field presence tracked?

Field type| Tracked?
Singular field| yes
Singular message field| yes
Field in a oneof| yes
Repeated field & map| no

**Proto3:**

Is field presence tracked?

Field type| Tracked?
_Other_ singular field| if defined as `optional`
Singular message field| yes
Field in a oneof| yes
Repeated field & map| no

**Edition 2023:**

Is field presence tracked?

Field type (in descending prescendence)| Tracked?
Repeated field & map| no
Message and Oneof fields| yes
Other singular fields if `features.field_presence` set to `IMPLICIT`| no
All other fields| yes


Skip navigation links

  * Overview
  * Package
  * Class
  * [Tree](https://protobuf.dev/reference/java/api-docs/overview-tree.html)
  * [Deprecated](https://protobuf.dev/reference/java/api-docs/deprecated-list.html)
  * [Index](https://protobuf.dev/reference/java/api-docs/index-all.html)
  * [Help](https://protobuf.dev/reference/java/api-docs/help-doc.html)

  * Prev
  * Next

  * [Frames](https://protobuf.dev/reference/java/api-docs/index.html?overview-summary.html)
  * [No Frames](https://protobuf.dev/reference/java/api-docs/overview-summary.html)

  * [All Classes](https://protobuf.dev/reference/java/api-docs/allclasses-noframe.html)

Packages Package | Description
[com.google.protobuf](https://protobuf.dev/reference/java/api-docs/com/google/protobuf/package-summary.html) |
[com.google.protobuf.compiler](https://protobuf.dev/reference/java/api-docs/com/google/protobuf/compiler/package-summary.html) |
[com.google.protobuf.util](https://protobuf.dev/reference/java/api-docs/com/google/protobuf/util/package-summary.html) |

Skip navigation links

  * Overview
  * Package
  * Class
  * [Tree](https://protobuf.dev/reference/java/api-docs/overview-tree.html)
  * [Deprecated](https://protobuf.dev/reference/java/api-docs/deprecated-list.html)
  * [Index](https://protobuf.dev/reference/java/api-docs/index-all.html)
  * [Help](https://protobuf.dev/reference/java/api-docs/help-doc.html)

  * Prev
  * Next

  * [Frames](https://protobuf.dev/reference/java/api-docs/index.html?overview-summary.html)
  * [No Frames](https://protobuf.dev/reference/java/api-docs/overview-summary.html)

  * [All Classes](https://protobuf.dev/reference/java/api-docs/allclasses-noframe.html)


# Support

Resources to support using Protocol Buffers.

This section of the documentation contains topics related to the support that the Protocol Buffers team provides to developers, including the timeframes for support for each version of a language library and migration guides to help you keep up with major version bumps.

##### [Version Support](https://protobuf.dev/support/version-support/)

A list of the support windows provided for language implementations.

##### [Debugging](https://protobuf.dev/support/debugging-playbook/)

Debugging common issues in Protocol Buffers.

##### [Migration Guide](https://protobuf.dev/support/migration/)

A list of the breaking changes made to versions of the libraries, and how to update your code to accommodate the changes.

##### [Cross-Version Runtime Guarantee](https://protobuf.dev/support/cross-version-runtime-guarantee/)

The guarantees that the language has for cross-version runtime compatibility.


# Kotlin Generated Code Guide

Describes exactly what Kotlin code the protocol buffer compiler generates for any given protocol definition, in addition to the code generated for Java.

Any differences between proto2, proto3, and editions generated code are highlighted—note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in both versions. You should read the [proto2 language guide](https://protobuf.dev/programming-guides/proto2), [proto3 language guide](https://protobuf.dev/programming-guides/proto3), and/or the [Editions guide](https://protobuf.dev/programming-guides/editions) before reading this document.

## Compiler Invocation

The protocol buffer compiler produces Kotlin code that builds on top of Java code. As a result, it must be invoked with two command-line flags, `--java_out=` and `--kotlin_out=`. The parameter to the `--java_out=` option is the directory where you want the compiler to write your Java output, and the same for the `--kotlin_out=`. For each `.proto` file input, the compiler creates a wrapper `.java` file containing a Java class which represents the `.proto` file itself.

**Regardless** of whether or not your `.proto` file contains a line like the following:

    option java_multiple_files = true;

The compiler will create separate `.kt` files for each of the classes and factory methods which it will generate for each top-level message declared in the `.proto` file.

The Java package name for each file is the same as that used by the generated Java code as described in the [Java generated code reference](https://protobuf.dev/reference/java/java-generated#package).

The output file is chosen by concatenating the parameter to `--kotlin_out=`, the package name (with periods [.] replaced with slashes [/]), and the suffix `Kt.kt` file name.

So, for example, let’s say you invoke the compiler as follows:

    protoc --proto_path=src --java_out=build/gen/java --kotlin_out=build/gen/kotlin src/foo.proto

If `foo.proto`’s Java package is `com.example` and it contains a message named `Bar`, then the protocol buffer compiler will generate the file `build/gen/kotlin/com/example/BarKt.kt`. The protocol buffer compiler will automatically create the `build/gen/kotlin/com` and `build/gen/kotlin/com/example` directories if needed. However, it will not create `build/gen/kotlin`, `build/gen`, or `build`; they must already exist. You can specify multiple `.proto` files in a single invocation; all output files will be generated at once.

## Messages

Given a simple message declaration:

    message FooBar {}

The protocol buffer compiler generates—in addition to the generated Java code—an object called `FooBarKt`, as well as two top-level functions, having the following structure:

    object FooBarKt {
      class Dsl private constructor { ... }
    inline fun fooBar(block: FooBarKt.Dsl.() -> Unit): FooBar
    inline fun FooBar.copy(block: FooBarKt.Dsl.() -> Unit): FooBar

### Nested Types

A message can be declared inside another message. For example:

    message Foo {
      message Bar { }

In this case, the compiler nests the `BarKt` object and the `bar` factory method inside `FooKt`, though the `copy` method remains top-level:

    object FooKt {
      class Dsl { ... }
      object BarKt {
        class Dsl private constructor { ... }
      inline fun bar(block: FooKt.BarKt.Dsl.() -> Unit): Foo.Bar
    inline fun foo(block: FooKt.Dsl.() -> Unit): Foo
    inline fun Foo.copy(block: FooKt.Dsl.() -> Unit): Foo
    inline fun Foo.Bar.copy(block: FooKt.BarKt.Dsl.() -> Unit): Foo.Bar

## Fields

In addition to the methods described in the previous section, the protocol buffer compiler generates mutable properties in the DSL for each field defined within the message in the `.proto` file. (Kotlin already infers read-only properties on the message object from the getters generated by Java.)

Note that properties always use camel-case naming, even if the field name in the `.proto` file uses lower-case with underscores ([as it should](https://protobuf.dev/programming-guides/style)). The case-conversion works as follows:

  1. For each underscore in the name, the underscore is removed, and the following letter is capitalized.
  2. If the name will have a prefix attached (for example, “clear”), the first letter is capitalized. Otherwise, it is lower-cased.

Thus, the field `foo_bar_baz` becomes `fooBarBaz`.

In a few special cases in which a field name conflicts with reserved words in Kotlin or methods already defined in the protobuf library, an extra underscore is appended. For instance, the clearer for a field named `in` is `clearIn_()`.

### Singular Fields

For this field definition:

    int32 foo = 1;

The compiler will generate the following accessors in the DSL:

  * `fun hasFoo(): Boolean`: Returns `true` if the field is set. This is not generated for fields using implicit presence.
  * `var foo: Int`: The current value of the field. If the field is not set, returns the default value.
  * `fun clearFoo()`: Clears the value of the field. After calling this, `hasFoo()` will return `false` and `getFoo()` will return the default value.

For other simple field types, the corresponding Java type is chosen according to the [scalar value types table](https://protobuf.dev/programming-guides/proto2#scalar). For message and enum types, the value type is replaced with the message or enum class. As the message type is still defined in Java, unsigned types in the message are represented using the standard corresponding signed types in the DSL, for compatibility with Java and older versions of Kotlin.

#### Embedded Message Fields

Note that there is no special handling of submessages. For example, if you have a field

    optional Foo my_foo = 1;

you must write

    myFoo = foo {
      ...

In general, this is because the compiler does not know whether `Foo` has a Kotlin DSL at all, or e.g. only has the Java APIs generated. This means that you do not have to wait for messages you depend on to add Kotlin code generation.

### Repeated Fields

For this field definition:

    repeated string foo = 1;

The compiler will generate the following members in the DSL:

  * `class FooProxy: DslProxy`, an unconstructable type used only in generics
  * `val fooList: DslList<String, FooProxy>`, a read-only view of the list of current elements in the repeated field
  * `fun DslList<String, FooProxy>.add(value: String)`, an extension function allowing elements to be added to the repeated field
  * `operator fun DslList<String, FooProxy>.plusAssign(value: String)`, an alias for `add`
  * `fun DslList<String, FooProxy>.addAll(values: Iterable<String>)`, an extension function allowing an `Iterable` of elements to be added to the repeated field
  * `operator fun DslList<String, FooProxy>.plusAssign(values: Iterable<String>)`, an alias for `addAll`
  * `operator fun DslList<String, FooProxy>.set(index: Int, value: String)`, an extension function setting the value of the element at the given zero-based inde
  * `fun DslList<String, FooProxy>.clear()`, an extension function clearing the contents of the repeated field

This unusual construction allows `fooList` to "behave like" a mutable list within the scope of the DSL, supporting only the methods supported by the underlying builder, while preventing mutability from "escaping" the DSL, which could cause confusing side effects.

For other simple field types, the corresponding Java type is chosen according to the [scalar value types table](https://protobuf.dev/programming-guides/proto2#scalar). For message and enum types, the type is the message or enum class.

### Oneof Fields

For this oneof field definition:

    oneof oneof_name {
        int32 foo = 1;
        ...

The compiler will generate the following accessor methods in the DSL:

  * `val oneofNameCase: OneofNameCase`: gets which, if any, of the `oneof_name` fields are set; see the [Java code reference](https://protobuf.dev/reference/java/java-generated#oneof) for the return type
  * `fun hasFoo(): Boolean`: Returns `true` if the oneof case is `FOO`.
  * `val foo: Int`: Returns the current value of `oneof_name` if the oneof case is `FOO`. Otherwise, returns the default value of this field.

For other simple field types, the corresponding Java type is chosen according to the [scalar value types table](https://protobuf.dev/programming-guides/proto2#scalar). For message and enum types, the value type is replaced with the message or enum class.

### Map Fields

For this map field definition:

    map<int32, int32> weight = 1;

The compiler will generate the following members in the DSL class:

  * `class WeightProxy private constructor(): DslProxy()`, an unconstructable type used only in generics
  * `val weight: DslMap<Int, Int, WeightProxy>`, a read-only view of the current entries in the map field
  * `fun DslMap<Int, Int, WeightProxy>.put(key: Int, value: Int)`: add the entry to this map field
  * `operator fun DslMap<Int, Int, WeightProxy>.put(key: Int, value: Int)`: alias for `put` using operator syntax
  * `fun DslMap<Int, Int, WeightProxy>.remove(key: Int)`: removes the entry associated with `key`, if present
  * `fun DslMap<Int, Int, WeightProxy>.putAll(map: Map<Int, Int>)`: adds all entries from the specified map to this map field, overwriting prior values for already present keys
  * `fun DslMap<Int, Int, WeightProxy>.clear()`: clears all entries from this map field

## Extensions

Given a proto2 or editions message with an extension range:

    message Foo {
      extensions 100 to 199;

The protocol buffer compiler will add the following methods to `FooKt.Dsl`:

  * `operator fun <T> get(extension: ExtensionLite<Foo, T>): T`: gets the current value of the extension field in the DSL
  * `operator fun <T> get(extension: ExtensionLite<Foo, List<T>>): ExtensionList<T, Foo>`: gets the current value of the repeated extension field in the DSL as a read-only `List`
  * `operator fun <T : Comparable<T>> set(extension: ExtensionLite<Foo, T>)`: sets the current value of the extension field in the DSL (for `Comparable` field types)
  * `operator fun <T : MessageLite> set(extension: ExtensionLite<Foo, T>)`: sets the current value of the extension field in the DSL (for message field types)
  * `operator fun set(extension: ExtensionLite<Foo, ByteString>)`: sets the current value of the extension field in the DSL (for `bytes` fields)
  * `operator fun contains(extension: ExtensionLite<Foo, *>): Boolean`: returns true if the extension field has a value
  * `fun clear(extension: ExtensionLite<Foo, *>)`: clears the extension field
  * `fun <E> ExtensionList<Foo, E>.add(value: E)`: adds a value to the repeated extension field
  * `operator fun <E> ExtensionList<Foo, E>.plusAssign(value: E)`: alias for `add` using operator syntax
  * `operator fun <E> ExtensionList<Foo, E>.addAll(values: Iterable<E>)`: adds multiple values to the repeated extension field
  * `operator fun <E> ExtensionList<Foo, E>.plusAssign(values: Iterable<E>)`: alias for `addAll` using operator syntax
  * `operator fun <E> ExtensionList<Foo, E>.set(index: Int, value: E)`: sets the element of the repeated extension field at the specified index
  * `inline fun ExtensionList<Foo, *>.clear()`: clears the elements of the repeated extension field

The generics here are complex, but the effect is that `this[extension] = value` works for every extension type except repeated extensions, and repeated extensions have "natural" list syntax that works similarly to non-extension repeated fields.

Given an extension definition:

    extend Foo {
      int32 bar = 123;

Java generates the “extension identifier” `bar`, which is used to “key” extension operations above.


# Ruby Generated Code Guide

Describes the API of message objects that the protocol buffer compiler generates for any given protocol definition.

You should read the language guides for [proto2](https://protobuf.dev/programming-guides/proto2), [proto3](https://protobuf.dev/programming-guides/proto3), or [editions](https://protobuf.dev/programming-guides/editions) before reading this document.

## Compiler Invocation

The protocol buffer compiler produces Ruby output when invoked with the `--ruby_out=` command-line flag. The parameter to the `--ruby_out=` option is the directory where you want the compiler to write your Ruby output. The compiler creates a `.rb` file for each `.proto` file input. The names of the output files are computed by taking the name of the `.proto` file and making two changes:

  * The extension (`.proto`) is replaced with `_pb.rb`.
  * The proto path (specified with the `--proto_path=` or `-I` command-line flag) is replaced with the output path (specified with the `--ruby_out=` flag).

So, for example, let’s say you invoke the compiler as follows:

    protoc --proto_path=src --ruby_out=build/gen src/foo.proto src/bar/baz.proto

The compiler will read the files `src/foo.proto` and `src/bar/baz.proto` and produce two output files: `build/gen/foo_pb.rb` and `build/gen/bar/baz_pb.rb`. The compiler will automatically create the directory `build/gen/bar` if necessary, but it will _not_ create `build` or `build/gen`; they must already exist.

## Packages

The package name defined in the `.proto` file is used to generate a module structure for the generated messages. Given a file like:

    package foo_bar.baz;

    message MyMessage {}

The protocol compiler generates an output message with the name `FooBar::Baz::MyMessage`.

However, if the `.proto` file contains the `ruby_package` option, like this:

    option ruby_package = "Foo::Bar";

then the generated output will give precedence to the `ruby_package` option instead and generate `Foo::Bar::MyMessage`.

## Messages

Given a simple message declaration:

    message Foo {}

The protocol buffer compiler generates a class called `Foo`. The generated class derives from the Ruby `Object` class (protos have no common base class). Unlike C++ and Java, Ruby generated code is unaffected by the `optimize_for` option in the `.proto` file; in effect, all Ruby code is optimized for code size.

You should _not_ create your own `Foo` subclasses. Generated classes are not designed for subclassing and may lead to "fragile base class" problems.

Ruby message classes define accessors for each field, and also provide the following standard methods:

  * `Message#dup`, `Message#clone`: Performs a shallow copy of this message and returns the new copy.
  * `Message#==`: Performs a deep equality comparison between two messages.
  * `Message#hash`: Computes a shallow hash of the message’s value.
  * `Message#to_hash`, `Message#to_h`: Converts the object to a ruby `Hash` object. Only the top-level message is converted.
  * `Message#inspect`: Returns a human-readable string representing this message.
  * `Message#[]`, `Message#[]=`: Gets or sets a field by string name. In the future this will probably also be used to get/set extensions.

The message classes also define the following methods as static. (In general we prefer static methods, since regular methods can conflict with field names you defined in your .proto file.)

  * `Message.decode(str)`: Decodes a binary protobuf for this message and returns it in a new instance.
  * `Message.encode(proto)`: Serializes a message object of this class to a binary string.
  * `Message.decode_json(str)`: Decodes a JSON text string for this message and returns it in a new instance.
  * `Message.encode_json(proto)`: Serializes a message object of this class to a JSON text string.
  * `Message.descriptor`: Returns the `Google::Protobuf::Descriptor` object for this message.

When you create a message, you can conveniently initialize fields in the constructor. Here is an example of constructing and using a message:

    message = MyMessage.new(int_field: 1,
                            string_field: "String",
                            repeated_int_field: [1, 2, 3, 4],
                            submessage_field: MyMessage::SubMessage.new(foo: 42))
    serialized = MyMessage.encode(message)

    message2 = MyMessage.decode(serialized)
    raise unless message2.int_field == 1

### Nested Types

A message can be declared inside another message. For example:

    message Foo {
      message Bar { }

In this case, the `Bar` class is declared as a class inside of `Foo`, so you can refer to it as `Foo::Bar`.

## Fields

For each field in a message type, there are accessor methods to set and get the field. So given a field `foo` you can write:

    message.foo = get_value()
    print message.foo

Whenever you set a field, the value is type-checked against the declared type of that field. If the value is of the wrong type (or out of range), an exception will be raised.

### Singular Fields

For singular primitive fields (numbers, strings, and boolean), the value you assign to the field should be of the correct type and must be in the appropriate range:

  * **Number types**: the value should be a `Fixnum`, `Bignum`, or `Float`. The value you assign must be exactly representable in the target type. So assigning `1.0` to an int32 field is ok, but assigning `1.2` is not.
  * **Boolean fields**: the value must be `true` or `false`. No other values will implicitly convert to true/false.
  * **Bytes fields**: the assigned value must be a `String` object. The protobuf library will duplicate the string, convert it to ASCII-8BIT encoding, and freeze it.
  * **String fields**: the assigned value must be a `String` object. The protobuf library will duplicate the string, convert it to UTF-8 encoding, and freeze it.

No automatic `#to_s`, `#to_i`, etc. calls will happen to perform automatic conversion. You should convert values yourself first, if necessary.

#### Checking Presence

Explicit field presence is determined by the `field_presence` feature (in editions), the `optional` keyword (in proto2/proto3), and the field type (message and oneof fields always have explicit presence). When a field has presence, you can check whether the field is set on a message by calling a generated `has_...?` method. Setting any value—even the default value—marks the field as present. Fields can be cleared by calling a different generated `clear_...` method.

For example, for a message `MyMessage` with an int32 field `foo`:

    message MyMessage {
      int32 foo = 1;

The presence of `foo` can be checked as follows:

    m = MyMessage.new
    raise if m.has_foo?
    m.foo = 0
    raise unless m.has_foo?
    m.clear_foo
    raise if m.has_foo?

### Singular Message Fields

Submessage fields always have presence, regardless of whether they’re marked as `optional`. Unset submessage fields return `nil`, so you can always tell if the message was explicitly set or not. To clear a submessage field, set its value explicitly to `nil`.

    if message.submessage_field.nil?
      puts "Submessage field is unset."
    else
      message.submessage_field = nil
      puts "Cleared submessage field."
    end

In addition to comparing and assigning `nil`, generated messages have `has_...` and `clear_...` methods, which behave the same as for basic types:

    if !message.has_submessage_field?
      puts "Submessage field is unset."
    else
      message.clear_submessage_field
      raise if message.has_submessage_field?
      puts "Cleared submessage field."
    end

When you assign a submessage, it must be a generated message object of the correct type.

It is possible to create message cycles when you assign submessages. For example:

    // foo.proto
    message RecursiveMessage {
      RecursiveMessage submessage = 1;

    # test.rb
    require 'foo'

    message = RecursiveMessage.new
    message.submessage = message

If you try to serialize this, the library will detect the cycle and fail to serialize.

### Repeated Fields

Repeated fields are represented using a custom class `Google::Protobuf::RepeatedField`. This class acts like a Ruby `Array` and mixes in `Enumerable`. Unlike a regular Ruby array, `RepeatedField` is constructed with a specific type and expects all of the array members to have the correct type. The types and ranges are checked just like message fields.

    int_repeatedfield = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])

    raise unless !int_repeatedfield.empty?

    # Raises TypeError.
    int_repeatedfield[2] = "not an int32"

    # Raises RangeError
    int_repeatedfield[2] = 2**33

    message.int32_repeated_field = int_repeatedfield

    # This isn't allowed; the regular Ruby array doesn't enforce types like we need.
    message.int32_repeated_field = [1, 2, 3, 4]

    # This is fine, since the elements are copied into the type-safe array.
    message.int32_repeated_field += [1, 2, 3, 4]

    # The elements can be cleared without reassigning.
    int_repeatedfield.clear
    raise unless int_repeatedfield.empty?

For repeated fields that contain messages, the constructor for `Google::Protobuf::RepeatedField` supports a variant with three arguments: `:message`, the class of the submessage, and the values to set:

    first_message = MySubMessage.new(foo: 42)
    second_message = MySubMessage.new(foo: 79)

    repeated_field = Google::Protobuf::RepeatedField.new(
        :message,
        MySubMessage,
        [first_message, second_message]
    )
    message.sub_message_repeated_field = repeated_field

The `RepeatedField` type supports all of the same methods as a regular Ruby `Array`. You can convert it to a regular Ruby Array with `repeated_field.to_a`.

Unlike singular fields, `has_...?` methods are never generated for repeated fields.

### Map Fields

Map fields are represented using a special class that acts like a Ruby `Hash` (`Google::Protobuf::Map`). Unlike a regular Ruby hash, `Map` is constructed with a specific type for the key and value and expects all of the map’s keys and values to have the correct type. The types and ranges are checked just like message fields and `RepeatedField` elements.

    int_string_map = Google::Protobuf::Map.new(:int32, :string)

    # Returns nil; items is not in the map.
    print int_string_map[5]

    # Raises TypeError, value should be a string
    int_string_map[11] = 200

    # Ok.
    int_string_map[123] = "abc"

    message.int32_string_map_field = int_string_map

## Enumerations

Since Ruby does not have native enums, we create a module for each enum with constants to define the values. Given the `.proto` file:

    message Foo {
      enum SomeEnum {
        VALUE_A = 0;
        VALUE_B = 5;
        VALUE_C = 1234;
      SomeEnum bar = 1;

You can refer to enum values like so:

    print Foo::SomeEnum::VALUE_A  # => 0
    message.bar = Foo::SomeEnum::VALUE_A

You may assign either a number or a symbol to an enum field. When reading the value back, it will be a symbol if the enum value is known, or a number if it is not.

With `OPEN` enums, which proto3 uses, any integer value can be assigned to the enum, even if that value is not defined in the enum.

    message.bar = 0
    puts message.bar.inspect  # => :VALUE_A
    message.bar = :VALUE_B
    puts message.bar.inspect  # => :VALUE_B
    message.bar = 999
    puts message.bar.inspect  # => 999

    # Raises: RangeError: Unknown symbol value for enum field.
    message.bar = :UNDEFINED_VALUE

    # Switching on an enum value is convenient.
    case message.bar
    when :VALUE_A
      # ...
    when :VALUE_B
      # ...
    when :VALUE_C
      # ...
    else
      # ...
    end

An enum module also defines the following utility methods:

  * `Foo::SomeEnum.lookup(number)`: Looks up the given number and returns its name, or `nil` if none was found. If more than one name has this number, returns the first that was defined.
  * `Foo::SomeEnum.resolve(symbol)`: Returns the number for this enum name, or `nil` if none was found.
  * `Foo::SomeEnum.descriptor`: Returns the descriptor for this enum.

## Oneof

Given a message with a oneof:

    message Foo {
      oneof test_oneof {
         string name = 1;
         int32 serial_number = 2;

The Ruby class corresponding to `Foo` will have members called `name` and `serial_number` with accessor methods just like regular fields. However, unlike regular fields, at most one of the fields in a oneof can be set at a time, so setting one field will clear the others.

    message = Foo.new

    # Fields have their defaults.
    raise unless message.name == ""
    raise unless message.serial_number == 0
    raise unless message.test_oneof == nil

    message.name = "Bender"
    raise unless message.name == "Bender"
    raise unless message.serial_number == 0
    raise unless message.test_oneof == :name

    # Setting serial_number clears name.
    message.serial_number = 2716057
    raise unless message.name == ""
    raise unless message.test_oneof == :serial_number

    # Setting serial_number to nil clears the oneof.
    message.serial_number = nil
    raise unless message.test_oneof == nil

For proto2 messages, oneof members have individual `has_...?` methods as well:

    message = Foo.new

    raise unless !message.has_test_oneof?
    raise unless !message.has_name?
    raise unless !message.has_serial_number?
    raise unless !message.has_test_oneof?

    message.name = "Bender"
    raise unless message.has_test_oneof?
    raise unless message.has_name?
    raise unless !message.has_serial_number?
    raise unless !message.has_test_oneof?


# Kotlin Reference

This section contains reference documentation for working with protocol buffers in Kotlin.

## Packages

Name
[com.google.protobuf.kotlin](https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)

##### [](https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)