# Parsing ProtoBuf Text Format

**URL:** https://discourse.julialang.org/t/parsing-protobuf-text-format/84721
**Category:** General Usage
**Tags:** question, io, serialization, protobuf
**Created:** [July 24, 2022, 6:24pm UTC](https://discourse.julialang.org/t/parsing-protobuf-text-format/84721 "2022-07-24T18:24:13Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![FireCrumb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/firecrumb/32/35370_2.png) [@FireCrumb](https://discourse.julialang.org/u/FireCrumb)
#### Post date: [July 24, 2022, 6:24pm UTC](https://discourse.julialang.org/t/parsing-protobuf-text-format/84721/1 "2022-07-24T18:24:13Z")

</div>

Hi, I’m trying to use [ProtoBuf.jl](https://github.com/JuliaIO/ProtoBuf.jl) to deserialize objects.

Managed to [generate code from .proto files](https://github.com/JuliaIO/ProtoBuf.jl/blob/master/PROTOC.md)

Now I want to read and write objects with [Protocol Buffer Text Format Language Specification](https://developers.google.com/protocol-buffers/docs/text-format-spec).  
However, I could only find [usage for binary readproto/writeproto](https://github.com/JuliaIO/ProtoBuf.jl/blob/master/USAGE.md).

How can I use [TextFormat](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.text_format)?  
Thanks!

---

<div class="post-metadata">

### Author: ![drvi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drvi/32/13236_2.png) [@drvi](https://discourse.julialang.org/u/drvi)
#### Post date: [July 25, 2022, 5:18am UTC](https://discourse.julialang.org/t/parsing-protobuf-text-format/84721/2 "2022-07-25T05:18:49Z")

</div>

Not ideal, but you should be able to convert the text format to binary with `protoc` using the `--encode`/`--decode` flags, see this [SO answer](https://stackoverflow.com/a/18877167).

---

<div class="post-metadata">

### Author: ![FireCrumb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/firecrumb/32/35370_2.png) [@FireCrumb](https://discourse.julialang.org/u/FireCrumb)
#### Post date: [July 27, 2022, 2:20am UTC](https://discourse.julialang.org/t/parsing-protobuf-text-format/84721/3 "2022-07-27T02:20:05Z")

</div>

Thanks!

I was able to build this solution:

```julia
using ProtoBuf
using protoc_jll

export protobuf_from_text, protobuf_to_text

# important: .proto files are required in runtime!

const _proj_path = normpath(joinpath(@ __FILE__ , "..", ".."))
const _proto_path = joinpath(_proj_path, "common")    
const _plugin_dir = abspath(joinpath(dirname(pathof(ProtoBuf)), "..", "plugin"))
const _plugin = joinpath(_plugin_dir, Sys.iswindows() ? "protoc-gen-julia_win.bat" : "protoc-gen-julia")
const ENV_ = copy(ENV)
ENV_["PATH"] = string(_plugin_dir, Sys.iswindows() ? ";" : ":", ENV_["PATH"])
ENV_["JULIA"] = joinpath(Sys.BINDIR, Base.julia_exename())

function protobuf_from_text(input::String, proto_type::Type{T}, proto_file="default.proto") where {T <: ProtoType}
    args = `--proto_path=$_proto_path --encode=mynamespace.$proto_type $proto_file`
    protoc_jll.protoc() do protoc_path
        inbuf = PipeBuffer()
        write(inbuf, input)
        outbuf = PipeBuffer()
        run(pipeline(setenv(`$protoc_path --plugin=protoc-gen-julia=$_plugin $args`, ENV_); stdin=inbuf, stdout=outbuf))
        return readproto(outbuf, proto_type())::T
    end
end

function protobuf_to_text(input::T, proto_file="default.proto") where {T <: ProtoType}
    proto_type = typeof(input)
    args = `--proto_path=$_proto_path --decode=mynamespace.$proto_type $proto_file`
    protoc_jll.protoc() do protoc_path
        inbuf = PipeBuffer()
        writeproto(inbuf, input)
        outbuf = PipeBuffer()
        run(pipeline(setenv(`$protoc_path --plugin=protoc-gen-julia=$_plugin $args`, ENV_); stdin=inbuf, stdout=outbuf))
        return read(outbuf, String)
    end
end

```

---

<div class="post-metadata">

### Author: ![FireCrumb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/firecrumb/32/35370_2.png) [@FireCrumb](https://discourse.julialang.org/u/FireCrumb)
#### Post date: [November 9, 2022, 8:59am UTC](https://discourse.julialang.org/t/parsing-protobuf-text-format/84721/4 "2022-11-09T08:59:17Z")

</div>

Updated code for [ProtoBuf.jl 1.0.0](https://discourse.julialang.org/t/ann-protobuf-jl-1-0-0/85885/11)

```julia
# important: .proto files are required in runtime!

const _proj_path = normpath(joinpath(@ __FILE__ , "..", ".."))
const _proto_path = "some_path"

const ENV_ = copy(ENV)
ENV_["JULIA"] = joinpath(Sys.BINDIR, Base.julia_exename())

function protobuf_from_text(
    input::String,
    proto_type::Type{T},
    proto_file = "my.proto"
) where {T}
    proto_type_name = string(Base.typename(proto_type).wrapper)
    args = `--proto_path=$_proto_path --encode=namespace.$proto_type_name $proto_file`
    protoc_jll.protoc() do protoc_path
        inbuf = PipeBuffer()
        write(inbuf, input)
        outbuf = PipeBuffer()
        run(pipeline(setenv(`$protoc_path $args`, ENV_); stdin = inbuf, stdout = outbuf))
        d = ProtoDecoder(outbuf)
        return decode(d, proto_type)::T
    end
end

function protobuf_to_text(input::T, proto_file = "my.proto") where {T}
    proto_type = typeof(input)
    proto_type_name = string(Base.typename(proto_type).wrapper)
    args = `--proto_path=$_proto_path --decode=namespace.$proto_type_name $proto_file`
    protoc_jll.protoc() do protoc_path
        inbuf = PipeBuffer()
        e = ProtoEncoder(inbuf)
        encode(e, input)
        outbuf = PipeBuffer()
        run(pipeline(setenv(`$protoc_path $args`, ENV_); stdin = inbuf, stdout = outbuf))
        return read(outbuf, String)
    end
end

```
