text:
#=
Functionality and definitions
related with the `Variables` types/subtypes
=#

############################################################
# Types and subtypes
############################################################

abstract type AbstractVariable{T,N} <: AbstractArray{T,N} end

# Variable (as stored in NetCDF file, without using
# add_offset, scale_factor and _FillValue)
mutable struct Variable{NetCDFType,N,TDS<:AbstractDataset} <: AbstractVariable{NetCDFType, N}
    ds::TDS
    varid::Cint
    dimids::NTuple{N,Cint}
    attrib::Attributes
end

############################################################
# Helper functions (internal)
############################################################
"Return all variable names"
listVar(ncid) = String[nc_inq_varname(ncid,varid)
                       for varid in nc_inq_varids(ncid)]

"""
    ds = NCDataset(var::CFVariable)
    ds = NCDataset(var::Variable)

Return the `NCDataset` containing the variable `var`.
"""
NCDataset(var::Variable) = var.ds

"""
    sz = size(var::Variable)

Return a tuple of integers with the size of the variable `var`.

!!! note

    Note that the size of a variable can change, i.e. for a variable with an
    unlimited dimension.
"""
Base.size(v::Variable{T,N}) where {T,N} = ntuple(i -> nc_inq_dimlen(v.ds.ncid,v.dimids[i]),Val(N))

"""
    renameVar(ds::NCDataset,oldname,newname)

Rename the variable called `oldname` to `newname`.
"""
function renameVar(ds::NCDataset,oldname::AbstractString,newname::AbstractString)
    # make sure that the file is in define mode
    defmode(ds)
    varid = nc_inq_varid(ds.ncid,oldname)
    nc_rename_var(ds.ncid,varid,newname)
    return nothing
end
export renameVar

############################################################
# Obtaining variables
############################################################

"""
    v = variable(ds::NCDataset,varname::String)

Return the NetCDF variable `varname` in the dataset `ds` as a
`NCDataset.Variable`. No scaling or other transformations are applied when the
variable `v` is indexed.
"""
function variable(ds::NCDataset,varname::SymbolOrString)
    varid = nc_inq_varid(ds.ncid,varname)
    name,nctype,dimids,nattr = nc_inq_var(ds.ncid,varid)
    ndims = length(dimids)
    shape = zeros(Int,ndims)

    for i = 1:ndims
        shape[ndims-i+1] = nc_inq_dimlen(ds.ncid,dimids[i])
    end

    attrib = Attributes(ds,varid)

    # reverse dimids to have the dimension order in Fortran style
    return Variable{nctype,ndims,NCDataset}(ds,varid,
                                  (reverse(dimids)...,),
                                  attrib)
end

export variable

"""
    NCDatasets.load!(ncvar::Variable, data, indices)

Loads a NetCDF variables `ncvar` in-place and puts the result in `data` along the
specified `indices`.

```julia
ds = Dataset("file.nc")
ncv = ds["vgos"].var;
# data must have the right shape and type
data = zeros(eltype(ncv),size(ncv));
NCDatasets.load!(ncv,data,:,:,:)
close(ds)

# loading a subset
data = zeros(5); # must have the right shape and type
load!(ds["temp"].var,data,:,1) # loads the 1st column
```

"""
@inline function load!(ncvar::NCDatasets.Variable{T,N}, data, indices::Union{Integer, UnitRange, StepRange, Colon}...) where {T,N}
    sizes =  size(ncvar)
    normalizedindices = normalizeindexes(sizes, indices)
    ind = to_indices(ncvar,normalizedindices)

    start,count,stride,jlshape = ncsub(ind)
    nc_get_vars!(ncvar.ds.ncid,ncvar.varid,start,count,stride,data)
end

@inline function load!(ncvar::NCDatasets.Variable{T,2}, data, i::Colon,j::UnitRange) where T
    # reversed and 0-based
    start = [first(j)-1,0]
    count = [length(j),size(ncvar,1)]
    nc_get_vara!(ncvar.ds.ncid,ncvar.varid,start,count,data)
end

"""
     data = loadragged(ncvar,index::Colon)

Load data from `ncvar` in the [contiguous ragged array representation](https://web.archive.org/web/20190111092546/http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#_contiguous_ragged_array_representation) as a
vector of vectors. It is typically used to load a list of profiles
or time series of different length each.

The [indexed ragged array representation](https://web.archive.org/web/20190111092546/http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#_indexed_ragged_array_representation) is currently not supported.
"""
function loadragged(ncvar,index::Colon)
    ds = NCDataset(ncvar)

    dimensionnames = dimnames(ncvar)
    if length(dimensionnames) !== 1
        throw(NetCDFError(-1, "NetCDF variable $(name(ncvar)) should have only one dimensions"))
    end
    dimname = dimensionnames[1]

    ncvarsizes = varbyattrib(ds,sample_dimension = dimname)
    if length(ncvarsizes) !== 1
        throw(NetCDFError(-1, "There should be exactly one NetCDF variable with the attribute 'sample_dimension' equal to '$(dimname)'"))
    end

    ncvarsize = ncvarsizes[1]
    varsize = ncvarsize.var[:]

    istart = 0;
    tmp = ncvar[:]

    T = typeof(view(tmp,1:varsize[1]))
    data = Vector{T}(undef,length(varsize))

    for i = 1:length(varsize)
        data[i] = view(tmp,istart+1:istart+varsize[i]);
        istart += varsize[i]
    end
    return data
end
export loadragged

############################################################
# User API regarding Variables
############################################################
"""
    dimnames(v::Variable)

Return a tuple of strings with the dimension names of the variable `v`.
"""
function dimnames(v::Variable{T,N}) where {T,N}
    return ntuple(i -> nc_inq_dimname(v.ds.ncid,v.dimids[i]),Val(N))
end
export dimnames

"""
    name(v::Variable)

Return the name of the NetCDF variable `v`.
"""
name(v::Variable) = nc_inq_varname(v.ds.ncid,v.varid)
export name

chunking(v::Variable,storage,chunksizes) = nc_def_var_chunking(v.ds.ncid,v.varid,storage,reverse(chunksizes))

"""
    storage,chunksizes = chunking(v::Variable)

Return the storage type (`:contiguous` or `:chunked`) and the chunk sizes
of the varable `v`.
"""
function chunking(v::Variable)
    storage,chunksizes = nc_inq_var_chunking(v.ds.ncid,v.varid)
    return storage,reverse(chunksizes)
end
export chunking

"""
    isshuffled,isdeflated,deflate_level = deflate(v::Variable)

Return compression information of the variable `v`. If shuffle
is `true`, then shuffling (byte interlacing) is activated. If
deflate is `true`, then the data chunks (see `chunking`) are
compressed using the compression level `deflate_level`
(0 means no compression and 9 means maximum compression).
"""
deflate(v::Variable,shuffle,deflate,deflate_level) = nc_def_var_deflate(v.ds.ncid,v.varid,shuffle,deflate,deflate_level)
deflate(v::Variable) = nc_inq_var_deflate(v.ds.ncid,v.varid)
export deflate

checksum(v::Variable,checksummethod) = nc_def_var_fletcher32(v.ds.ncid,v.varid,checksummethod)

"""
   checksummethod = checksum(v::Variable)

Return the checksum method of the variable `v` which can be either
be `:fletcher32` or `:nochecksum`.
"""
checksum(v::Variable) = nc_inq_var_fletcher32(v.ds.ncid,v.varid)
export checksum

function fillmode(v::Variable)
    no_fill,fv = nc_inq_var_fill(v.ds.ncid, v.varid)
    return no_fill,fv
end
export fillmode

"""
    fv = fillvalue(v::Variable)
    fv = fillvalue(v::CFVariable)

Return the fill-value of the variable `v`.
"""
function fillvalue(v::Variable{NetCDFType,N}) where {NetCDFType,N}
    no_fill,fv = nc_inq_var_fill(v.ds.ncid, v.varid)
    return fv::NetCDFType
end
export fillvalue

"""
    a = nomissing(da)

Return the values of the array `da` of type `Array{Union{T,Missing},N}`
(potentially containing missing values) as a regular Julia array `a` of the same
element type. It raises an error if the array contains at least one missing value.

"""
function nomissing(da::AbstractArray{Union{T,Missing},N}) where {T,N}
    if any(ismissing, da)
        error("arrays contains missing values (values equal to the fill values attribute in the NetCDF file)")
    end
    if VERSION >= v"1.2"
        # Illegal instruction (core dumped) in Julia 1.0.5
        # but works on Julia 1.2
        return Array{T,N}(da)
    else
        # old
        if isempty(da)
            return Array{T,N}([])
        else
            return replace(da, missing => da[1])
        end
    end
end

nomissing(a::AbstractArray) = a

"""
    a = nomissing(da,value)

Retun the values of the array `da` of type `Array{Union{T,Missing},N}`
as a regular Julia array `a` by replacing all missing value by `value`
(converted to type `T`).
This function is identical to `coalesce.(da,T(value))` where T is the element
tyoe of `da`.
## Example:

```julia-repl
julia> nomissing([missing,1.,2.],NaN)
# returns [NaN, 1.0, 2.0]
```
"""
function nomissing(da::Array{Union{T,Missing},N},value) where {T,N}
    return replace(da, missing => T(value))
end

nomissing(a::AbstractArray,value) = a
export nomissing

function Base.getindex(v::Variable,indexes::Int...)
    datamode(v.ds)
    return nc_get_var1(eltype(v),v.ds.ncid,v.varid,[i-1 for i in indexes[ndims(v):-1:1]])
end

function Base.setindex!(v::Variable{T,N},data,indexes::Int...) where N where T
    @debug "$(@__LINE__)"
    datamode(v.ds)
    # use zero-based indexes and reversed order
    nc_put_var1(v.ds.ncid,v.varid,[i-1 for i in indexes[ndims(v):-1:1]],T(data))
    return data
end

function Base.getindex(v::Variable{T,N},indexes::Colon...) where {T,N}
    datamode(v.ds)
    # special case for scalar NetCDF variable
    if N == 0
        data = Ref(zero(T))
        nc_get_var!(v.ds.ncid,v.varid,data)
        return data[]
    else
        data = Array{T,N}(undef,size(v))
        nc_get_var!(v.ds.ncid,v.varid,data)
        return data
    end
end

function Base.setindex!(v::Variable{T,N},data::T,indexes::Colon...) where {T,N}
    @debug "setindex! colon $data"
    datamode(v.ds) # make sure that the file is in data mode
    tmp = fill(data,size(v))

    nc_put_var(v.ds.ncid,v.varid,tmp)
    return data
end

# call to v .= 123
function Base.setindex!(v::Variable{T,N},data::Number) where {T,N}
    @debug "setindex! $data"
    datamode(v.ds) # make sure that the file is in data mode
    tmp = fill(convert(T,data),size(v))

    nc_put_var(v.ds.ncid,v.varid,tmp)
    return data
end

Base.setindex!(v::Variable,data::Number,indexes::Colon...) = setindex!(v::Variable,data)

function Base.setindex!(v::Variable{T,N},data::AbstractArray{T,N},indexes::Colon...) where {T,N}
    datamode(v.ds) # make sure that the file is in data mode

    nc_put_var(v.ds.ncid,v.varid,data)
    return data
end

function Base.setindex!(v::Variable{T,N},data::AbstractArray{T2,N},indexes::Colon...) where {T,T2,N}
    datamode(v.ds) # make sure that the file is in data mode
    tmp =
        if T <: Integer
            round.(T,data)
        else
            convert(Array{T,N},data)
        end

    nc_put_var(v.ds.ncid,v.varid,tmp)
    return data
end

function ncsub(indexes::NTuple{N,T}) where N where T
    rindexes = reverse(indexes)
    count  = Int[length(i)  for i in rindexes]
    start  = Int[first(i)-1 for i in rindexes]     # use zero-based indexes
    stride = Int[step(i)    for i in rindexes]
    jlshape = length.(indexes)::NTuple{N,Int}
    return start,count,stride,jlshape
end

function Base.getindex(v::Variable{T,N},indexes::TR...) where {T,N} where TR <: Union{StepRange{Int,Int},UnitRange{Int}}
    start,count,stride,jlshape = ncsub(indexes[1:N])
    data = Array{T,N}(undef,jlshape)

    datamode(v.ds)
    nc_get_vars!(v.ds.ncid,v.varid,start,count,stride,data)
    return data
end

function Base.setindex!(v::Variable{T,N},data::T,indexes::StepRange{Int,Int}...) where {T,N}
    datamode(v.ds) # make sure that the file is in data mode
    start,count,stride,jlshape = ncsub(indexes[1:ndims(v)])
    tmp = fill(data,jlshape)
    nc_put_vars(v.ds.ncid,v.varid,start,count,stride,tmp)
    return data
end

function Base.setindex!(v::Variable{T,N},data::Number,indexes::StepRange{Int,Int}...) where {T,N}
    datamode(v.ds) # make sure that the file is in data mode
    start,count,stride,jlshape = ncsub(indexes[1:ndims(v)])
    tmp = fill(convert(T,data),jlshape)
    nc_put_vars(v.ds.ncid,v.varid,start,count,stride,tmp)
    return data
end

function Base.setindex!(v::Variable{T,N},data::Array{T,N},indexes::StepRange{Int,Int}...) where {T,N}
    datamode(v.ds) # make sure that the file is in data mode
    start,count,stride,jlshape = ncsub(indexes[1:ndims(v)])
    nc_put_vars(v.ds.ncid,v.varid,start,count,stride,data)
    return data
end

# data can be Array{T2,N} or BitArray{N}
function Base.setindex!(v::Variable{T,N},data::AbstractArray,indexes::StepRange{Int,Int}...) where {T,N}
    datamode(v.ds) # make sure that the file is in data mode
    start,count,stride,jlshape = ncsub(indexes[1:ndims(v)])

    tmp = convert(Array{T,ndims(data)},data)
    nc_put_vars(v.ds.ncid,v.varid,start,count,stride,tmp)

    return data
end

_normalizeindex(n,ind::Colon) = 1:1:n
_normalizeindex(n,ind::Int) = ind:1:ind
_normalizeindex(n,ind::UnitRange) = StepRange(ind)
_normalizeindex(n,ind::StepRange) = ind
_normalizeindex(n,ind) = error("unsupported index")

_dropindex(ind::Int) = 1
_dropindex(ind) = Colon()

# indexes can be longer than sz
function normalizeindexes(sz,indexes)
    return ntuple(i -> _normalizeindex(sz[i],indexes[i]), length(sz))
end

function Base.getindex(v::Variable,indexes::Union{Int,Colon,UnitRange{Int},StepRange{Int,Int}}...)
    ind = normalizeindexes(size(v),indexes)
    drop_index = _dropindex.(indexes)
    # drop any dimension which was indexed with a scalar
    # TODO: avoid copy
    data = v[ind...][drop_index...]
    return data
end

function Base.setindex!(v::Variable,data,indexes::Union{Int,Colon,UnitRange{Int},StepRange{Int,Int}}...)
    ind = normalizeindexes(size(v),indexes)

    # make arrays out of scalars
    if ndims(data) == 0
        data = fill(data,length.(ind))
    end

    return v[ind...] = data
end

function Base.show(io::IO,v::AbstractVariable; indent="")
    delim = " × "
    dims =
        try
            dimnames(v)
        catch err
            if isa(err,NetCDFError)
                if err.code == NC_EBADID
                    print(io,"NetCDF variable (file closed)")
                    return
                end
            end
            rethrow()
        end
    sz = size(v)

    printstyled(io, indent, name(v),color=variable_color())
    if length(sz) > 0
        print(io,indent," (",join(sz,delim),")\n")
        print(io,indent,"  Datatype:    ",eltype(v),"\n")
        print(io,indent,"  Dimensions:  ",join(dims,delim),"\n")
    else
        print(io,indent,"\n")
    end

    if length(v.attrib) > 0
        print(io,indent,"  Attributes:\n")
        show(io,v.attrib; indent = "$(indent)   ")
    end
end


text:
module B_structs
using  O_structs
export D__type    # structure of problem data

mutable struct D__type
   ms::ms_type    # data of investment problem sets
   mp::mp_type    # data of investment problem parameters
   ps::ps_type    # data of operational problem sets
   pp::pp_type    # data of operational problem parameters
  unc::u_type     # data of uncertain parameters
 algm::Int64      # algorithm used
   γs::Float64    # preset parameter for level method, 0 gives classical method
    J::Int64      # maximum number of iteration
    δ::Float64    # convergence tolerance
end

end

ext: jl


text:
module TwoBlocksPipeline
export twoblockspipelinesearch

using Distributed
#nprocs() == 1 && addprocs(; exeflags = "--project")
nprocs() == 1 && addprocs()
@everywhere using AutoMLPipeline
@everywhere using DataFrames
@everywhere using AutoMLPipeline: score
@everywhere using Random

# disable truncation of dataframes columns
import Base.show
show(df::AbstractDataFrame) = show(df,truncate=0)
show(io::IO,df::AbstractDataFrame) = show(io,df;truncate=0)

# define scalers
const rb     = SKPreprocessor("RobustScaler",Dict(:name=>"rb"))
const pt     = SKPreprocessor("PowerTransformer",Dict(:name=>"pt"))
const norm   = SKPreprocessor("Normalizer",Dict(:name=>"norm"))
const mx     = SKPreprocessor("MinMaxScaler",Dict(:name=>"mx"))
const std    = SKPreprocessor("StandardScaler",Dict(:name=>"std"))
# define extractors
const pca    = SKPreprocessor("PCA",Dict(:name=>"pca"))
const fa     = SKPreprocessor("FactorAnalysis",Dict(:name=>"fa"))
const ica    = SKPreprocessor("FastICA",Dict(:name=>"ica"))
# define learners
const rf     = SKLearner("RandomForestClassifier",Dict(:name => "rf"))
const ada    = SKLearner("AdaBoostClassifier",Dict(:name => "ada"))
const gb     = SKLearner("GradientBoostingClassifier",Dict(:name => "gb"))
const lsvc   = SKLearner("LinearSVC",Dict(:name => "lsvc"))
const rbfsvc = SKLearner("SVC",Dict(:name => "rbfsvc"))
const dt     = SKLearner("DecisionTreeClassifier",Dict(:name =>"dt"))
# preprocessing
const noop = Identity(Dict(:name =>"noop"))
const ohe  = OneHotEncoder(Dict(:name=>"ohe"))
const catf = CatFeatureSelector(Dict(:name=>"catf"))
const numf = NumFeatureSelector(Dict(:name=>"numf"))

const vscalers =    [rb,pt,norm,mx,std,noop]
const vextractors = [pca,fa,ica,noop]
const vlearners =   [rf,gb,lsvc,rbfsvc,ada,dt]
const learnerdict = Dict("rf"=>rf,"gb"=>gb,"lsvc"=>lsvc,"rbfsvc"=>rbfsvc,"ada"=>ada,"dt"=>dt)

function oneblock_pipeline_factory(scalers,extractors,learners)
   results = @distributed (vcat) for lr in learners
      @distributed (vcat) for xt in extractors
         @distributed (vcat) for sc in scalers
            # baseline preprocessing
            prep = @pipeline ((catf |> ohe) + numf)
            # one-block prp
            expx = @pipeline prep |> (sc |> xt) |> lr
            scn   = sc.name[1:end - 4];xtn = xt.name[1:end - 4]; lrn = lr.name[1:end - 4]
            pname = "($scn |> $xtn) |> $lrn"
            DataFrame(Description=pname,Pipeline=expx)
         end
      end
   end
   return results
end

function evaluate_pipeline(dfpipelines,X,Y;folds=3)
   res=@distributed (vcat) for prow in eachrow(dfpipelines)
      perf = crossvalidate(prow.Pipeline,X,Y;nfolds=folds)
      DataFrame(Description=prow.Description,mean=perf.mean,sd=perf.std,prow.Pipeline)
   end
   return res
end

function twoblock_pipeline_factory(scalers,extractors,learners)
   results = @distributed (vcat) for lr in learners
      @distributed (vcat) for xt1 in extractors
         @distributed (vcat) for xt2 in extractors
            @distributed (vcat) for sc1 in scalers
               @distributed (vcat) for sc2 in scalers
                  prep = @pipeline ((catf |> ohe) + numf)
                  expx = @pipeline prep |> ((sc1 |> xt1) + (sc2 |> xt2)) |> lr
                  scn1   = sc1.name[1:end - 4];xtn1 = xt1.name[1:end - 4];
                  scn2   = sc2.name[1:end - 4];xtn2 = xt2.name[1:end - 4];
                  lrn = lr.name[1:end - 4]
                  pname = "($scn1 |> $xtn1) + ($scn2 |> $xtn2) |> $lrn"
                  DataFrame(Description=pname,Pipeline=expx)
               end
            end
         end
      end
   end
   return results
end

function model_selection_pipeline(learners)
   results = @distributed (vcat) for lr in learners
      prep = @pipeline ((catf |> ohe) + numf)
      expx = @pipeline prep |> (rb |> pca)  |> lr
      pname = "(rb |> pca) |> $(lr.name[1:end-4])"
      DataFrame(Description=pname,Pipeline=expx)
   end
   return results
end

function lname(n::Learner)
   n.name[1:end-4]
end

function twoblockspipelinesearch(X::DataFrame,Y::Vector;scalers=vscalers,extractors=vextractors,learners=vlearners)
   dfpipes = model_selection_pipeline(vlearners)
   # find the best model by evaluating the models
   modelsperf = evaluate_pipeline(dfpipes,X,Y;folds=10)
   sort!(modelsperf,:mean, rev = true)
   # get the string name of the top model
   bestm =  filter(x->occursin(x,modelsperf.Description[1]),lname.(vlearners))[1]
   # get corresponding model object
   bestmodel = learnerdict[bestm]
   # use the best model to generate pipeline search
   dfp = twoblock_pipeline_factory(vscalers,vextractors,[bestmodel])
   # evaluate the pipeline
   bestp=evaluate_pipeline(dfp,X,Y;folds=3)
   sort!(bestp,:mean, rev = true)
   show(bestp;allrows=false,truncate=1,allcols=false)
   println()
   optmodel = bestp[1,:]
   return (optmodel.Description,optmodel.mean,optmodel.sd,optmodel.Pipeline)
end

end

@everywhere using Main.TwoBlocksPipeline
#
#dataset = getiris()
#X = dataset[:,1:4]
#Y = dataset[:,5] |> collect
#
#twoblockspipelinesearch(X,Y)


text:
struct GenericVendor <: AbstractVendor end
struct GenericProduct <: AbstractProduct end

mutable struct CSVImporter{T <: AbstractSchema} <: AbstractImporter
    isenabled::Bool
    schema::T
end

function isenabled(importer::CSVImporter)
    return importer.isenabled
end

function enable!(importer::CSVImporter)
    importer.isenabled = true
end

function disable!(importer::CSVImporter)
    importer.isenabled  = false
end

function (load::CSVImporter{<:AbstractSchema})(path::Path)
    disable!(load)
    load_dataframe(path)
end

function load_dataframe(path::Path)
    path₁ = joinpath(get_directory(path), get_filename(path))
    data = nothing
    if is_readable_file(path₁)
        try
            data = CSV.File(path₁) |> DataFrame
        catch e
            println(e)
            CImGui.OpenPopup("Has the file been corrupted?")
        end
    else
        CImGui.OpenPopup("Do you have permission to read the file?")
    end
    handle_import_error_messages()
    data
end

function load_dataframe(path::Path, header::Vector{String})
    path₁ = joinpath(get_directory(path), get_filename(path))
    data = nothing
    if is_readable_file(path₁)
        try
            data = CSV.File(path₁; header = header) |> DataFrame
        catch e
            println(e)
            CImGui.OpenPopup("Has the file been corrupted?")
        end
    else
        CImGui.OpenPopup("Do you have permission to read the file?")
    end
    handle_import_error_messages()
    data
end

function handle_import_error_messages()
    if CImGui.BeginPopupModal("Has the file been corrupted?", C_NULL, CImGui.ImGuiWindowFlags_AlwaysAutoResize)
        CImGui.Text("Unable to open the specified file.\nPlease verify that: \n   (1) the file has not been corrupted; \n   (2) you have permission to access the file.\n\n")
        CImGui.Separator()
        CImGui.Button("OK", (120, 0)) && CImGui.CloseCurrentPopup()
        CImGui.SetItemDefaultFocus()
        CImGui.EndPopup()
    end

    if CImGui.BeginPopupModal("Do you have permission to read the file?", C_NULL, CImGui.ImGuiWindowFlags_AlwaysAutoResize)
        CImGui.Text("Unable to access the specified file.\nPlease verify that: \n   (1) the file exists; \n   (2) you have permission to read the file.\n\n")
        CImGui.Separator()
        CImGui.Button("OK", (120, 0)) && CImGui.CloseCurrentPopup()
        CImGui.SetItemDefaultFocus()
        CImGui.EndPopup()
    end

    if CImGui.BeginPopupModal("Have you opened the appropriate file?", C_NULL, CImGui.ImGuiWindowFlags_AlwaysAutoResize)
    CImGui.Text("The file format does not to conform to the expected schema.\nPlease verify that the data in the file follows the expected convention.\n\n")
    CImGui.Separator()
    CImGui.Button("OK", (120, 0)) && CImGui.CloseCurrentPopup()
    CImGui.SetItemDefaultFocus()
    CImGui.EndPopup()
    end
end


text:
module Callbacks

# specialized to be automatically invoked when a model exception is triggered internally
# accepts (model <: AbstractModel, ex::TypeConversionException)
# returns model <: AbstractModel
function on_exception end

# specialize to be automatically invoked when model data is retrieved from the DB (on `find` methods)
# it will be invoked for each field in the model
# accepts (model <: AbstractModel, field_name::Symbol, value::Any)
# returns model <: AbstractModel
function on_find end

# specialize to be automatically invoked after the object is retrieved from the DB
# accepts (model <: AbstractModel)
# return model <: AbstractModel
function after_find end

# specialize to be automatically invoked when the object is being peristed to the DB
# accepts (model <: AbstractModel, field_name::Symbol, value::Any)
# returns model <: AbstractModel
function on_save end

# specialize to be automatically invoked before the object is being peristed to the DB
# accepts (model <: AbstractModel)
# returns model <: AbstractModel
function before_save end

# specialize to be automatically invoked after the object is being peristed to the DB
# accepts (model <: AbstractModel)
# returns model <: AbstractModel
function after_save end

end


text:
abstract type Surface end

"""
Specify a surface as list of geometric objects.
"""
mutable struct SurfaceAssembly <: Surface
    objects::Array{Surface,1}
end

"""
Geometric sphere surface.
"""
struct Sphere <: Surface
    center::Vector
    radius::Real
    material::Material
end

"""
    hit(sa, ray, tmin, tmax)

Obtain the closest hit record for a ray intersecting the objects stored in a `SurfaceAssembly`.
"""
function hit(sa::SurfaceAssembly, ray::Ray, tmin::Real, tmax::Real)
    # hit record
    rec = nothing
    closest_so_far = tmax
    for obj in sa.objects
        currec, t = hit(obj, ray, tmin, closest_so_far)
        if currec != nothing
            closest_so_far = t;
            rec = currec
        end
    end
    return (rec, closest_so_far)
end

"""
    hit(sphere, ray, tmin, tmax)

Obtain the hit record for a ray intersecting a sphere.
"""
function hit(sphere::Sphere, ray::Ray, tmin::Real, tmax::Real)
    oc = ray.origin - sphere.center
    a = dot(ray.direction, ray.direction)
    b = dot(oc, ray.direction)
    c = dot(oc, oc) - sphere.radius^2;
    discriminant = b^2 - a*c
    if discriminant > 0
        # solutions of the quadratic equation
        t1 = -(b + sign(b)*sqrt(discriminant)) / a
        t2 = c / (a * t1)
        # smaller solution first
        for t in sort([t1, t2])
            if tmin <= t && t < tmax
                point = point_at_parameter(ray, t)
                normal = (point - sphere.center) / sphere.radius
                return (HitRecord(point, normal, sphere.material), t)
            end
        end
    end
    return (nothing, tmax)
end


text:
export rational_reconstruction, farey_lift, div, valence, leading_coefficient,
       trailing_coefficient, constant_coefficient, factor_mod_pk, factor_mod_pk_init, hensel_lift

function PolynomialRing(R::Ring)
  return PolynomialRing(R, "_x")
end

function FlintFiniteField(p::Integer)
  return ResidueRing(ZZ, p)
end

function FlintFiniteField(p::fmpz)
  return ResidueRing(ZZ, p)
end

function fmpz(a::GenRes{Nemo.fmpz})
  return a.data
end

function lift(R::FlintIntegerRing, a::GenRes{Nemo.fmpz})
  return a.data
end

function Base.call(R::FlintIntegerRing, a::GenRes{Nemo.fmpz})
  return a.data
end

## given some r/s = a mod b and deg(r) = n, deg(s) <= m find r,s
## a and b better be polynomials in the same poly ring.
## seems to work for Q (Qx) and Fp experimentally
#
# possibly should be rewritten to use an asymptotically (and practically)
# faster algorithm. For Q possibly using CRT and fast Fp techniques
# Algorithm copies from the bad-primes paper

function rational_reconstruction{S}(a::PolyElem{S}, b::PolyElem{S}, n::Int, m::Int)
  R = a.parent
  if degree(a) <= n return true, a, R(1); end

  M = MatrixSpace(R, 2, 2)()
  M[1,1] = b
  M[2,1] = a
  M[2,2] = R(1)

  T = MatrixSpace(R, 2, 2)()
  T[1,2] = R(1)
  T[2,1] = R(1)
  while degree(M[2,1]) > n
    q, r = divrem(M[1,1], M[2,1])
    T[2,2] = -q
    M = T*M
  end
  if degree(M[2,2]) <= m
    return true, M[2,1], M[2,2]
  end

  return false, M[2,1], M[2,2]
end

function rational_reconstruction{T}(a::PolyElem{T}, b::PolyElem{T})
  return rational_reconstruction(a, b, div(degree(b), 2), div(degree(b), 2))
end

# to appease the Singular crowd...
farey_lift = rational_reconstruction

# in at least 2 examples produces the same result as Magma
# can do experiments to see if dedicated Berlekamp Massey would be
# faster as well as experiments if Berlekamp Massey yields faster
# rational_reconstruction as well.
# Idea of using the same agorithm due to E. Thome
#

function berlekamp_massey{T}(a::Array{T, 1})
  Rx,x = PolynomialRing(parent(a[1]))
  f = Rx(a)
  xn= x^length(a)

  fl, n, d = rational_reconstruction(f, xn)
  if fl
    return true, d*(inv(trailing_coefficient(d)))
  else
    return false, Rx(0)
  end
end

function div(f::PolyElem, g::PolyElem)
  q,r = divrem(f,g)
  return q
end

doc"""
***
  valence(f::PolyElem) -> RingElem

>  The last non-zero coefficient of f
"""
function valence(f::PolyElem)
  for i=0:degree(f)
    c = coeff(f, i)
    if !iszero(c)
      return c
    end
  end
  return c
end

doc"""
***
  leading_coefficient(f::PolyElem) -> RingElem

>  The last leading coefficient of f.
"""
function leading_coefficient(f::PolyElem)
  return coeff(f, degree(f))
end

doc"""
***
  trailing_coefficient(f::PolyElem) -> RingElem
  constant_coefficient(f::PolyElem) -> RingElem

>  The constant coefficient of f.
"""
function trailing_coefficient(f::PolyElem)
  return coeff(f, 0)
end

constant_coefficient = trailing_coefficient

function resultant(f::fmpz_poly, g::fmpz_poly, d::fmpz, nb::Int)
  z = fmpz()
  ccall((:fmpz_poly_resultant_modular_div, :libflint), Void,
     (Ptr{fmpz}, Ptr{fmpz_poly}, Ptr{fmpz_poly}, Ptr{fmpz}, Int),
     &z, &f, &g, &d, nb)
  return z
end

##############################################################
#
# Hensel
#
##############################################################

type fmpz_poly_raw  ## fmpz_poly without parent like in c
  coeffs::Ptr{Void}
  alloc::Int
  length::Int

  function fmpz_poly_raw()
    error("should not get called")
    z = new()
    ccall((:fmpz_poly_init, :libflint), Void, (Ptr{fmpz_poly},), &z)
        finalizer(z, _fmpz_poly_raw_clear_fn)
    return z
  end
end

function _fmpz_poly_raw_clear_fn(a::fmpz_poly)
  ccall((:fmpz_poly_clear, :libflint), Void, (Ptr{fmpz_poly},), &a)
end

type fmpz_poly_factor
  c::Int   # really an fmpz  - but there is no fmpz_raw to be flint compatible
  poly::Ptr{fmpz_poly_raw}
  exp::Ptr{Int}
  _num::Int
  _alloc::Int

  function fmpz_poly_factor()
    z = new()
    ccall((:fmpz_poly_factor_init, :libflint), Void,
            (Ptr{fmpz_poly_factor}, ), &z)
    finalizer(z, _fmpz_poly_factor_clear_fn)
    return z
  end
end

function _fmpz_poly_factor_clear_fn(a::fmpz_poly_factor)
  ccall((:fmpz_poly_factor_clear, :libflint), Void,
          (Ptr{fmpz_poly_factor}, ), &a)
end

function factor_to_dict(a::fmpz_poly_factor)
  res = Dict{fmpz_poly,Int}()
  Zx,x = PolynomialRing(FlintZZ, "x")
  for i in 1:a._num
    f = Zx()
    ccall((:fmpz_poly_set, :libflint), Void, (Ptr{fmpz_poly}, Ptr{fmpz_poly_raw}), &f, a.poly+(i-1)*sizeof(fmpz_poly_raw))
    res[f] = unsafe_load(a.exp, i)
  end
  return res
end

function show(io::IO, a::fmpz_poly_factor)
  ccall((:fmpz_poly_factor_print, :libflint), Void, (Ptr{fmpz_poly_factor}, ), &a)
end

type HenselCtx
  f::fmpz_poly
  p::UInt

  LF :: fmpz_poly_factor
  link::Ptr{Int}
  v::Ptr{fmpz_poly_raw}
  w::Ptr{fmpz_poly_raw}
  N::UInt
  prev::UInt
  r::Int  #for the cleanup
  lf:: Nemo.nmod_poly_factor

  function HenselCtx(f::fmpz_poly, p::fmpz)
    a = new()
    a.f = f
    a.p = UInt(p)
    Zx,x = PolynomialRing(FlintZZ, "x")
    Rx,x = PolynomialRing(ResidueRing(FlintZZ, p), "x")
    a.lf = Nemo.nmod_poly_factor(UInt(p))
    ccall((:nmod_poly_factor, :libflint), UInt,
          (Ptr{Nemo.nmod_poly_factor}, Ptr{nmod_poly}), &(a.lf), &Rx(f))
    r = a.lf._num
    a.r = r
    a.LF = fmpz_poly_factor()
    @assert r > 1  #flint restriction
    a.v = ccall((:flint_malloc, :libflint), Ptr{fmpz_poly_raw}, (Int, ), (2*r-2)*sizeof(fmpz_poly_raw))
    a.w = ccall((:flint_malloc, :libflint), Ptr{fmpz_poly_raw}, (Int, ), (2*r-2)*sizeof(fmpz_poly_raw))
    for i=1:(2*r-2)
      ccall((:fmpz_poly_init, :libflint), Void, (Ptr{fmpz_poly_raw}, ), a.v+(i-1)*sizeof(fmpz_poly_raw))
      ccall((:fmpz_poly_init, :libflint), Void, (Ptr{fmpz_poly_raw}, ), a.w+(i-1)*sizeof(fmpz_poly_raw))
    end
    a.link = ccall((:flint_calloc, :libflint), Ptr{Int}, (Int, Int), r, sizeof(Int))
    a.N = 0
    a.prev = 0
    finalizer(a, HenselCtx_free)
    return a
  end

  function free_fmpz_poly_array(p::Ptr{fmpz_poly_raw}, r::Int)
    for i=1:(2*r-2)
      ccall((:fmpz_poly_clear, :libflint), Void, (Ptr{fmpz_poly_raw}, ), p+(i-1)*sizeof(fmpz_poly_raw))
    end
    ccall((:flint_free, :libflint), Void, (Ptr{fmpz_poly_raw}, ), p)
  end
  function free_int_array(a::Ptr{Int})
    ccall((:flint_free, :libflint), Void, (Ptr{Int}, ), a)
  end
  function HenselCtx_free(a::HenselCtx)
    free_fmpz_poly_array(a.v, a.r)
    free_fmpz_poly_array(a.w, a.r)
    free_int_array(a.link)
  end
end

function show(io::IO, a::HenselCtx)
  println("factorisation of $(a.f) modulo $(a.p)^$(a.N)")
  if a.N > 0
    d = factor_to_dict(a.LF)
    println("currently: $d")
  end
end

function start_lift(a::HenselCtx, N::Int)
  a.prev = ccall((:_fmpz_poly_hensel_start_lift, :libflint), UInt,
       (Ptr{fmpz_poly_factor}, Ptr{Int}, Ptr{fmpz_poly_raw}, Ptr{fmpz_poly_raw}, Ptr{fmpz_poly}, Ptr{Nemo.nmod_poly_factor}, Int),
       &a.LF, a.link, a.v, a.w, &a.f, &a.lf, N)
  a.N = N
end

function continue_lift(a::HenselCtx, N::Int)
  a.prev = ccall((:_fmpz_poly_hensel_continue_lift, :libflint), Int,
       (Ptr{fmpz_poly_factor}, Ptr{Int}, Ptr{fmpz_poly_raw}, Ptr{fmpz_poly_raw}, Ptr{fmpz_poly}, UInt, UInt, Int, Ptr{fmpz}),
       &a.LF, a.link, a.v, a.w, &a.f, a.prev, a.N, N, &fmpz(a.p))
  a.N = N
end

doc"""
***
  factor_mod_pk(f::fmpz_poly, p::Int, k::Int) -> Dict{fmpz_poly, Int}

>  For f that is square-free modulo p, return the factorisation modulo p^k.
"""
function factor_mod_pk(f::fmpz_poly, p::Int, k::Int)
  H = HenselCtx(f, fmpz(p))
  start_lift(H, k)
  return factor_to_dict(H.LF)
end

doc"""
***
  factor_mod_pk_init(f::fmpz_poly, p::Int) -> HenselCtx

>  For f that is square-free modulo p, return a structure that allows to compute
>  the factorisaion modulo p^k for any k
"""
function factor_mod_pk_init(f::fmpz_poly, p::Int)
  H = HenselCtx(f, fmpz(p))
  return H
end

doc"""
***
  factor_mod_pk(H::HenselCtx, k::Int) -> RingElem

>  Using the result of factor_mod_pk_init, return a factorisation modulo p^k
"""
function factor_mod_pk(H::HenselCtx, k::Int)
  @assert k>= H.N
  if H.N == 0
    start_lift(H, k)
  else
    continue_lift(H, k)
  end
  return factor_to_dict(H.LF)
end

#I think, experimentally, that p = Q^i, p1 = Q^j and j<= i is the condition to make it tick.
function hensel_lift!(G::fmpz_poly, H::fmpz_poly, A::fmpz_poly, B::fmpz_poly, f::fmpz_poly, g::fmpz_poly, h::fmpz_poly, a::fmpz_poly, b::fmpz_poly, p::fmpz, p1::fmpz)
  ccall((:fmpz_poly_hensel_lift, :libflint), Void, (Ptr{fmpz_poly}, Ptr{fmpz_poly},  Ptr{fmpz_poly},  Ptr{fmpz_poly},  Ptr{fmpz_poly},  Ptr{fmpz_poly},  Ptr{fmpz_poly}, Ptr{fmpz_poly}, Ptr{fmpz_poly}, Ptr{fmpz}, Ptr{fmpz}), &G, &H, &A, &B, &f, &g, &h, &a, &b, &p, &p1)
end

doc"""
***
  hensel_lift(f::fmpz_poly, g::fmpz_poly, h::fmpz_poly, p::fmpz, k::Int) -> (fmpz_poly, fmpz_poly)

>  Given f = gh modulo p for g, h coprime modulo p, compute G, H s.th. f = GH mod p^k and
>  G = g mod p, H = h mod p.
"""
function hensel_lift(f::fmpz_poly, g::fmpz_poly, h::fmpz_poly, p::fmpz, k::Int)
  Rx, x = PolynomialRing(ResidueRing(FlintZZ, p))
  fl, a, b = gcdx(Rx(g), Rx(h))
  @assert isone(fl)
  @assert k>= 2
  ## if one of the cofactors is zero, this crashes.
  ## this can only happen if one of the factors is one. In this case, the other
  ## is essentially f and f would be a legal answer. Probably reduced mod p^k
  ## with all non-negative coefficients
  ## for now:
  @assert !iszero(a) && !iszero(b)
  a = lift(parent(g), a)
  b = lift(parent(g), b)
  G = parent(g)()
  H = parent(g)()
  A = parent(g)()
  B = parent(g)()
  g = deepcopy(g)
  h = deepcopy(h)

  # the idea is to have a good chain of approximations, ie.
  # to reach p^10, one should do p, p^2, p^3, p^5, p^10
  # rather than p, p^2, p^4, p^8, p^10
  # the chain has the same length, but smaller entries.
  l = [k]
  while k>1
    k = div(k+1, 2)
    push!(l, k)
  end
  ll = []
  for i=length(l)-1:-1:1
    push!(ll, l[i] - l[i+1])
  end
  P = p
  for i in ll
    p1 = p^i
    hensel_lift!(G, H, A, B, f, g, h, a, b, P, p1)
    G, g = g, G
    H, h = h, H
    A, a = a, A
    B, b = b, B
    P *= p1
  end
  return g, h
end

doc"""
***
  hensel_lift(f::fmpz_poly, g::fmpz_poly, p::fmpz, k::Int) -> (fmpz_poly, fmpz_poly)

>  Given f and g such that g is a divisor of f mod p and g and f/g are coprime, compute a hensel lift of g modulo p^k.
"""
function hensel_lift(f::fmpz_poly, g::fmpz_poly, p::fmpz, k::Int)
  Rx, x = PolynomialRing(ResidueRing(FlintZZ, p))
  h = lift(parent(f), div(Rx(f), Rx(g)))
  return hensel_lift(f, g, h, p, k)[1]
end

function fmpq_poly_to_nmod_poly_raw!(r::nmod_poly, a::fmpq_poly)
  ccall((:_fmpz_vec_get_nmod_poly, :libhecke), Void, (Ptr{nmod_poly}, Ptr{Int}, Int), &r, a.coeffs, a.length)
  p = r.mod_n
  den = ccall((:fmpz_fdiv_ui, :libflint), UInt, (Ptr{Int}, UInt), &a.den, p)
  if den != UInt(1)
    den = ccall((:n_invmod, :libflint), UInt, (UInt, UInt), den, p)
    mul!(r, r, den)
  end
end

function fmpq_poly_to_nmod_poly(Rx::Nemo.NmodPolyRing, f::fmpq_poly)
  g = Rx()
  fmpq_poly_to_nmod_poly_raw!(g, f)
  return g
end

function fmpz_poly_to_nmod_poly_raw!(r::nmod_poly, a::fmpz_poly)
  ccall((:fmpz_poly_get_nmod_poly, :libflint), Void,
                  (Ptr{nmod_poly}, Ptr{fmpz_poly}), &r, &a)

end

function fmpz_poly_to_nmod_poly(Rx::Nemo.NmodPolyRing, f::fmpz_poly)
  g = Rx()
  fmpz_poly_to_nmod_poly_raw!(g, f)
  return g
end


text:
using Test, MLToolkit
using Distributions: Poisson

@testset "DisplacedPoisson" begin
    for _ = 1:NUM_RANDTESTS
        λ = rand() * 10

        p = Poisson(λ)

        x = 0:1:100
        y_p = pdf.(Ref(p), x)
        # When r equals 0, displaced Poisson reduces to normal Poisson.
        # Thus we can check the p.d.f using the Poisson (from Distributions.jl).
        dpeqv = DisplacedPoisson(λ, 0.0)
        y_dpeqv = pdf.(Ref(dpeqv), x)
        @test all(isapprox.(y_p, y_dpeqv))

        m_p = mode(p)
        m_dpeqv = mode(dpeqv)
        @test m_p == m_dpeqv

        @test minimum(dpeqv) == 0
        @test maximum(dpeqv) == Inf

        @test string(dpeqv) == "DisplacedPoisson($(round(λ; sigdigits=3)), 0.0)"
    end
end


text:
# syntax: proto2
mutable struct UninterpretedOption_NamePart <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function UninterpretedOption_NamePart(; kwargs...)
        obj = new(meta(UninterpretedOption_NamePart), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct UninterpretedOption_NamePart
const __meta_UninterpretedOption_NamePart = Ref{ProtoMeta}()
function meta(::Type{UninterpretedOption_NamePart})
    ProtoBuf.metalock() do
        if !isassigned(__meta_UninterpretedOption_NamePart)
            __meta_UninterpretedOption_NamePart[] = target = ProtoMeta(UninterpretedOption_NamePart)
            req = Symbol[:name_part,:is_extension]
            allflds = Pair{Symbol,Union{Type,String}}[:name_part => AbstractString, :is_extension => Bool]
            meta(target, UninterpretedOption_NamePart, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_UninterpretedOption_NamePart[]
    end
end
function Base.getproperty(obj::UninterpretedOption_NamePart, name::Symbol)
    if name === :name_part
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :is_extension
        return (obj.__protobuf_jl_internal_values[name])::Bool
    else
        getfield(obj, name)
    end
end

mutable struct UninterpretedOption <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function UninterpretedOption(; kwargs...)
        obj = new(meta(UninterpretedOption), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct UninterpretedOption
const __meta_UninterpretedOption = Ref{ProtoMeta}()
function meta(::Type{UninterpretedOption})
    ProtoBuf.metalock() do
        if !isassigned(__meta_UninterpretedOption)
            __meta_UninterpretedOption[] = target = ProtoMeta(UninterpretedOption)
            fnum = Int[2,3,4,5,6,7,8]
            allflds = Pair{Symbol,Union{Type,String}}[:name => Base.Vector{UninterpretedOption_NamePart}, :identifier_value => AbstractString, :positive_int_value => UInt64, :negative_int_value => Int64, :double_value => Float64, :string_value => Array{UInt8,1}, :aggregate_value => AbstractString]
            meta(target, UninterpretedOption, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_UninterpretedOption[]
    end
end
function Base.getproperty(obj::UninterpretedOption, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption_NamePart}
    elseif name === :identifier_value
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :positive_int_value
        return (obj.__protobuf_jl_internal_values[name])::UInt64
    elseif name === :negative_int_value
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :double_value
        return (obj.__protobuf_jl_internal_values[name])::Float64
    elseif name === :string_value
        return (obj.__protobuf_jl_internal_values[name])::Array{UInt8,1}
    elseif name === :aggregate_value
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    else
        getfield(obj, name)
    end
end

const FieldOptions_CType = (;[
    Symbol("STRING") => Int32(0),
    Symbol("CORD") => Int32(1),
    Symbol("STRING_PIECE") => Int32(2),
]...)

const FieldOptions_JSType = (;[
    Symbol("JS_NORMAL") => Int32(0),
    Symbol("JS_STRING") => Int32(1),
    Symbol("JS_NUMBER") => Int32(2),
]...)

mutable struct FieldOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FieldOptions(; kwargs...)
        obj = new(meta(FieldOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FieldOptions
const __meta_FieldOptions = Ref{ProtoMeta}()
function meta(::Type{FieldOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FieldOptions)
            __meta_FieldOptions[] = target = ProtoMeta(FieldOptions)
            val = Dict{Symbol,Any}(:ctype => FieldOptions_CType.STRING, :jstype => FieldOptions_JSType.JS_NORMAL, :lazy => false, :deprecated => false, :weak => false)
            fnum = Int[1,2,6,5,3,10,999]
            allflds = Pair{Symbol,Union{Type,String}}[:ctype => Int32, :packed => Bool, :jstype => Int32, :lazy => Bool, :deprecated => Bool, :weak => Bool, :uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, FieldOptions, allflds, ProtoBuf.DEF_REQ, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FieldOptions[]
    end
end
function Base.getproperty(obj::FieldOptions, name::Symbol)
    if name === :ctype
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :packed
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :jstype
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :lazy
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :deprecated
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :weak
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

mutable struct MessageOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function MessageOptions(; kwargs...)
        obj = new(meta(MessageOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct MessageOptions
const __meta_MessageOptions = Ref{ProtoMeta}()
function meta(::Type{MessageOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_MessageOptions)
            __meta_MessageOptions[] = target = ProtoMeta(MessageOptions)
            val = Dict{Symbol,Any}(:message_set_wire_format => false, :no_standard_descriptor_accessor => false, :deprecated => false)
            fnum = Int[1,2,3,7,999]
            allflds = Pair{Symbol,Union{Type,String}}[:message_set_wire_format => Bool, :no_standard_descriptor_accessor => Bool, :deprecated => Bool, :map_entry => Bool, :uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, MessageOptions, allflds, ProtoBuf.DEF_REQ, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_MessageOptions[]
    end
end
function Base.getproperty(obj::MessageOptions, name::Symbol)
    if name === :message_set_wire_format
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :no_standard_descriptor_accessor
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :deprecated
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :map_entry
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

mutable struct EnumOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EnumOptions(; kwargs...)
        obj = new(meta(EnumOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EnumOptions
const __meta_EnumOptions = Ref{ProtoMeta}()
function meta(::Type{EnumOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EnumOptions)
            __meta_EnumOptions[] = target = ProtoMeta(EnumOptions)
            val = Dict{Symbol,Any}(:deprecated => false)
            fnum = Int[2,3,999]
            allflds = Pair{Symbol,Union{Type,String}}[:allow_alias => Bool, :deprecated => Bool, :uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, EnumOptions, allflds, ProtoBuf.DEF_REQ, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EnumOptions[]
    end
end
function Base.getproperty(obj::EnumOptions, name::Symbol)
    if name === :allow_alias
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :deprecated
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

mutable struct ExtensionRangeOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ExtensionRangeOptions(; kwargs...)
        obj = new(meta(ExtensionRangeOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct ExtensionRangeOptions
const __meta_ExtensionRangeOptions = Ref{ProtoMeta}()
function meta(::Type{ExtensionRangeOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ExtensionRangeOptions)
            __meta_ExtensionRangeOptions[] = target = ProtoMeta(ExtensionRangeOptions)
            fnum = Int[999]
            allflds = Pair{Symbol,Union{Type,String}}[:uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, ExtensionRangeOptions, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ExtensionRangeOptions[]
    end
end
function Base.getproperty(obj::ExtensionRangeOptions, name::Symbol)
    if name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

const MethodOptions_IdempotencyLevel = (;[
    Symbol("IDEMPOTENCY_UNKNOWN") => Int32(0),
    Symbol("NO_SIDE_EFFECTS") => Int32(1),
    Symbol("IDEMPOTENT") => Int32(2),
]...)

mutable struct MethodOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function MethodOptions(; kwargs...)
        obj = new(meta(MethodOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct MethodOptions
const __meta_MethodOptions = Ref{ProtoMeta}()
function meta(::Type{MethodOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_MethodOptions)
            __meta_MethodOptions[] = target = ProtoMeta(MethodOptions)
            val = Dict{Symbol,Any}(:deprecated => false, :idempotency_level => MethodOptions_IdempotencyLevel.IDEMPOTENCY_UNKNOWN)
            fnum = Int[33,34,999]
            allflds = Pair{Symbol,Union{Type,String}}[:deprecated => Bool, :idempotency_level => Int32, :uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, MethodOptions, allflds, ProtoBuf.DEF_REQ, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_MethodOptions[]
    end
end
function Base.getproperty(obj::MethodOptions, name::Symbol)
    if name === :deprecated
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :idempotency_level
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

const FileOptions_OptimizeMode = (;[
    Symbol("SPEED") => Int32(1),
    Symbol("CODE_SIZE") => Int32(2),
    Symbol("LITE_RUNTIME") => Int32(3),
]...)

mutable struct FileOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FileOptions(; kwargs...)
        obj = new(meta(FileOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FileOptions
const __meta_FileOptions = Ref{ProtoMeta}()
function meta(::Type{FileOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FileOptions)
            __meta_FileOptions[] = target = ProtoMeta(FileOptions)
            val = Dict{Symbol,Any}(:java_multiple_files => false, :java_string_check_utf8 => false, :optimize_for => FileOptions_OptimizeMode.SPEED, :cc_generic_services => false, :java_generic_services => false, :py_generic_services => false, :php_generic_services => false, :deprecated => false, :cc_enable_arenas => false)
            fnum = Int[1,8,10,20,27,9,11,16,17,18,42,23,31,36,37,39,40,41,44,45,999]
            allflds = Pair{Symbol,Union{Type,String}}[:java_package => AbstractString, :java_outer_classname => AbstractString, :java_multiple_files => Bool, :java_generate_equals_and_hash => Bool, :java_string_check_utf8 => Bool, :optimize_for => Int32, :go_package => AbstractString, :cc_generic_services => Bool, :java_generic_services => Bool, :py_generic_services => Bool, :php_generic_services => Bool, :deprecated => Bool, :cc_enable_arenas => Bool, :objc_class_prefix => AbstractString, :csharp_namespace => AbstractString, :swift_prefix => AbstractString, :php_class_prefix => AbstractString, :php_namespace => AbstractString, :php_metadata_namespace => AbstractString, :ruby_package => AbstractString, :uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, FileOptions, allflds, ProtoBuf.DEF_REQ, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FileOptions[]
    end
end
function Base.getproperty(obj::FileOptions, name::Symbol)
    if name === :java_package
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :java_outer_classname
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :java_multiple_files
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :java_generate_equals_and_hash
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :java_string_check_utf8
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :optimize_for
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :go_package
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :cc_generic_services
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :java_generic_services
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :py_generic_services
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :php_generic_services
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :deprecated
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :cc_enable_arenas
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :objc_class_prefix
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :csharp_namespace
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :swift_prefix
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :php_class_prefix
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :php_namespace
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :php_metadata_namespace
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :ruby_package
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

mutable struct EnumValueOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EnumValueOptions(; kwargs...)
        obj = new(meta(EnumValueOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EnumValueOptions
const __meta_EnumValueOptions = Ref{ProtoMeta}()
function meta(::Type{EnumValueOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EnumValueOptions)
            __meta_EnumValueOptions[] = target = ProtoMeta(EnumValueOptions)
            val = Dict{Symbol,Any}(:deprecated => false)
            fnum = Int[1,999]
            allflds = Pair{Symbol,Union{Type,String}}[:deprecated => Bool, :uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, EnumValueOptions, allflds, ProtoBuf.DEF_REQ, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EnumValueOptions[]
    end
end
function Base.getproperty(obj::EnumValueOptions, name::Symbol)
    if name === :deprecated
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

mutable struct OneofOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function OneofOptions(; kwargs...)
        obj = new(meta(OneofOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct OneofOptions
const __meta_OneofOptions = Ref{ProtoMeta}()
function meta(::Type{OneofOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_OneofOptions)
            __meta_OneofOptions[] = target = ProtoMeta(OneofOptions)
            fnum = Int[999]
            allflds = Pair{Symbol,Union{Type,String}}[:uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, OneofOptions, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_OneofOptions[]
    end
end
function Base.getproperty(obj::OneofOptions, name::Symbol)
    if name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

mutable struct ServiceOptions <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ServiceOptions(; kwargs...)
        obj = new(meta(ServiceOptions), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct ServiceOptions
const __meta_ServiceOptions = Ref{ProtoMeta}()
function meta(::Type{ServiceOptions})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ServiceOptions)
            __meta_ServiceOptions[] = target = ProtoMeta(ServiceOptions)
            val = Dict{Symbol,Any}(:deprecated => false)
            fnum = Int[33,999]
            allflds = Pair{Symbol,Union{Type,String}}[:deprecated => Bool, :uninterpreted_option => Base.Vector{UninterpretedOption}]
            meta(target, ServiceOptions, allflds, ProtoBuf.DEF_REQ, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ServiceOptions[]
    end
end
function Base.getproperty(obj::ServiceOptions, name::Symbol)
    if name === :deprecated
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :uninterpreted_option
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{UninterpretedOption}
    else
        getfield(obj, name)
    end
end

const FieldDescriptorProto_Type = (;[
    Symbol("TYPE_DOUBLE") => Int32(1),
    Symbol("TYPE_FLOAT") => Int32(2),
    Symbol("TYPE_INT64") => Int32(3),
    Symbol("TYPE_UINT64") => Int32(4),
    Symbol("TYPE_INT32") => Int32(5),
    Symbol("TYPE_FIXED64") => Int32(6),
    Symbol("TYPE_FIXED32") => Int32(7),
    Symbol("TYPE_BOOL") => Int32(8),
    Symbol("TYPE_STRING") => Int32(9),
    Symbol("TYPE_GROUP") => Int32(10),
    Symbol("TYPE_MESSAGE") => Int32(11),
    Symbol("TYPE_BYTES") => Int32(12),
    Symbol("TYPE_UINT32") => Int32(13),
    Symbol("TYPE_ENUM") => Int32(14),
    Symbol("TYPE_SFIXED32") => Int32(15),
    Symbol("TYPE_SFIXED64") => Int32(16),
    Symbol("TYPE_SINT32") => Int32(17),
    Symbol("TYPE_SINT64") => Int32(18),
]...)

const FieldDescriptorProto_Label = (;[
    Symbol("LABEL_OPTIONAL") => Int32(1),
    Symbol("LABEL_REQUIRED") => Int32(2),
    Symbol("LABEL_REPEATED") => Int32(3),
]...)

mutable struct FieldDescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FieldDescriptorProto(; kwargs...)
        obj = new(meta(FieldDescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FieldDescriptorProto
const __meta_FieldDescriptorProto = Ref{ProtoMeta}()
function meta(::Type{FieldDescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FieldDescriptorProto)
            __meta_FieldDescriptorProto[] = target = ProtoMeta(FieldDescriptorProto)
            fnum = Int[1,3,4,5,6,2,7,9,10,8]
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :number => Int32, :label => Int32, :_type => Int32, :type_name => AbstractString, :extendee => AbstractString, :default_value => AbstractString, :oneof_index => Int32, :json_name => AbstractString, :options => FieldOptions]
            meta(target, FieldDescriptorProto, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FieldDescriptorProto[]
    end
end
function Base.getproperty(obj::FieldDescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :number
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :label
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :_type
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :type_name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :extendee
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :default_value
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :oneof_index
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :json_name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::FieldOptions
    else
        getfield(obj, name)
    end
end

mutable struct DescriptorProto_ExtensionRange <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function DescriptorProto_ExtensionRange(; kwargs...)
        obj = new(meta(DescriptorProto_ExtensionRange), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct DescriptorProto_ExtensionRange
const __meta_DescriptorProto_ExtensionRange = Ref{ProtoMeta}()
function meta(::Type{DescriptorProto_ExtensionRange})
    ProtoBuf.metalock() do
        if !isassigned(__meta_DescriptorProto_ExtensionRange)
            __meta_DescriptorProto_ExtensionRange[] = target = ProtoMeta(DescriptorProto_ExtensionRange)
            allflds = Pair{Symbol,Union{Type,String}}[:start => Int32, :_end => Int32, :options => ExtensionRangeOptions]
            meta(target, DescriptorProto_ExtensionRange, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_DescriptorProto_ExtensionRange[]
    end
end
function Base.getproperty(obj::DescriptorProto_ExtensionRange, name::Symbol)
    if name === :start
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :_end
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::ExtensionRangeOptions
    else
        getfield(obj, name)
    end
end

mutable struct MethodDescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function MethodDescriptorProto(; kwargs...)
        obj = new(meta(MethodDescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct MethodDescriptorProto
const __meta_MethodDescriptorProto = Ref{ProtoMeta}()
function meta(::Type{MethodDescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_MethodDescriptorProto)
            __meta_MethodDescriptorProto[] = target = ProtoMeta(MethodDescriptorProto)
            val = Dict{Symbol,Any}(:client_streaming => false, :server_streaming => false)
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :input_type => AbstractString, :output_type => AbstractString, :options => MethodOptions, :client_streaming => Bool, :server_streaming => Bool]
            meta(target, MethodDescriptorProto, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_MethodDescriptorProto[]
    end
end
function Base.getproperty(obj::MethodDescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :input_type
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :output_type
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::MethodOptions
    elseif name === :client_streaming
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :server_streaming
        return (obj.__protobuf_jl_internal_values[name])::Bool
    else
        getfield(obj, name)
    end
end

mutable struct EnumValueDescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EnumValueDescriptorProto(; kwargs...)
        obj = new(meta(EnumValueDescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EnumValueDescriptorProto
const __meta_EnumValueDescriptorProto = Ref{ProtoMeta}()
function meta(::Type{EnumValueDescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EnumValueDescriptorProto)
            __meta_EnumValueDescriptorProto[] = target = ProtoMeta(EnumValueDescriptorProto)
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :number => Int32, :options => EnumValueOptions]
            meta(target, EnumValueDescriptorProto, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EnumValueDescriptorProto[]
    end
end
function Base.getproperty(obj::EnumValueDescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :number
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::EnumValueOptions
    else
        getfield(obj, name)
    end
end

mutable struct EnumDescriptorProto_EnumReservedRange <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EnumDescriptorProto_EnumReservedRange(; kwargs...)
        obj = new(meta(EnumDescriptorProto_EnumReservedRange), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EnumDescriptorProto_EnumReservedRange
const __meta_EnumDescriptorProto_EnumReservedRange = Ref{ProtoMeta}()
function meta(::Type{EnumDescriptorProto_EnumReservedRange})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EnumDescriptorProto_EnumReservedRange)
            __meta_EnumDescriptorProto_EnumReservedRange[] = target = ProtoMeta(EnumDescriptorProto_EnumReservedRange)
            allflds = Pair{Symbol,Union{Type,String}}[:start => Int32, :_end => Int32]
            meta(target, EnumDescriptorProto_EnumReservedRange, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EnumDescriptorProto_EnumReservedRange[]
    end
end
function Base.getproperty(obj::EnumDescriptorProto_EnumReservedRange, name::Symbol)
    if name === :start
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :_end
        return (obj.__protobuf_jl_internal_values[name])::Int32
    else
        getfield(obj, name)
    end
end

mutable struct EnumDescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EnumDescriptorProto(; kwargs...)
        obj = new(meta(EnumDescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EnumDescriptorProto
const __meta_EnumDescriptorProto = Ref{ProtoMeta}()
function meta(::Type{EnumDescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EnumDescriptorProto)
            __meta_EnumDescriptorProto[] = target = ProtoMeta(EnumDescriptorProto)
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :value => Base.Vector{EnumValueDescriptorProto}, :options => EnumOptions, :reserved_range => Base.Vector{EnumDescriptorProto_EnumReservedRange}, :reserved_name => Base.Vector{AbstractString}]
            meta(target, EnumDescriptorProto, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EnumDescriptorProto[]
    end
end
function Base.getproperty(obj::EnumDescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :value
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{EnumValueDescriptorProto}
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::EnumOptions
    elseif name === :reserved_range
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{EnumDescriptorProto_EnumReservedRange}
    elseif name === :reserved_name
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{AbstractString}
    else
        getfield(obj, name)
    end
end

mutable struct OneofDescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function OneofDescriptorProto(; kwargs...)
        obj = new(meta(OneofDescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct OneofDescriptorProto
const __meta_OneofDescriptorProto = Ref{ProtoMeta}()
function meta(::Type{OneofDescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_OneofDescriptorProto)
            __meta_OneofDescriptorProto[] = target = ProtoMeta(OneofDescriptorProto)
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :options => OneofOptions]
            meta(target, OneofDescriptorProto, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_OneofDescriptorProto[]
    end
end
function Base.getproperty(obj::OneofDescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::OneofOptions
    else
        getfield(obj, name)
    end
end

mutable struct DescriptorProto_ReservedRange <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function DescriptorProto_ReservedRange(; kwargs...)
        obj = new(meta(DescriptorProto_ReservedRange), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct DescriptorProto_ReservedRange
const __meta_DescriptorProto_ReservedRange = Ref{ProtoMeta}()
function meta(::Type{DescriptorProto_ReservedRange})
    ProtoBuf.metalock() do
        if !isassigned(__meta_DescriptorProto_ReservedRange)
            __meta_DescriptorProto_ReservedRange[] = target = ProtoMeta(DescriptorProto_ReservedRange)
            allflds = Pair{Symbol,Union{Type,String}}[:start => Int32, :_end => Int32]
            meta(target, DescriptorProto_ReservedRange, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_DescriptorProto_ReservedRange[]
    end
end
function Base.getproperty(obj::DescriptorProto_ReservedRange, name::Symbol)
    if name === :start
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :_end
        return (obj.__protobuf_jl_internal_values[name])::Int32
    else
        getfield(obj, name)
    end
end

mutable struct DescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function DescriptorProto(; kwargs...)
        obj = new(meta(DescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct DescriptorProto
const __meta_DescriptorProto = Ref{ProtoMeta}()
function meta(::Type{DescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_DescriptorProto)
            __meta_DescriptorProto[] = target = ProtoMeta(DescriptorProto)
            fnum = Int[1,2,6,3,4,5,8,7,9,10]
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :field => Base.Vector{FieldDescriptorProto}, :extension => Base.Vector{FieldDescriptorProto}, :nested_type => Base.Vector{DescriptorProto}, :enum_type => Base.Vector{EnumDescriptorProto}, :extension_range => Base.Vector{DescriptorProto_ExtensionRange}, :oneof_decl => Base.Vector{OneofDescriptorProto}, :options => MessageOptions, :reserved_range => Base.Vector{DescriptorProto_ReservedRange}, :reserved_name => Base.Vector{AbstractString}]
            meta(target, DescriptorProto, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_DescriptorProto[]
    end
end
function Base.getproperty(obj::DescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :field
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{FieldDescriptorProto}
    elseif name === :extension
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{FieldDescriptorProto}
    elseif name === :nested_type
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{DescriptorProto}
    elseif name === :enum_type
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{EnumDescriptorProto}
    elseif name === :extension_range
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{DescriptorProto_ExtensionRange}
    elseif name === :oneof_decl
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{OneofDescriptorProto}
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::MessageOptions
    elseif name === :reserved_range
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{DescriptorProto_ReservedRange}
    elseif name === :reserved_name
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{AbstractString}
    else
        getfield(obj, name)
    end
end

mutable struct ServiceDescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function ServiceDescriptorProto(; kwargs...)
        obj = new(meta(ServiceDescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct ServiceDescriptorProto
const __meta_ServiceDescriptorProto = Ref{ProtoMeta}()
function meta(::Type{ServiceDescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_ServiceDescriptorProto)
            __meta_ServiceDescriptorProto[] = target = ProtoMeta(ServiceDescriptorProto)
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :method => Base.Vector{MethodDescriptorProto}, :options => ServiceOptions]
            meta(target, ServiceDescriptorProto, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_ServiceDescriptorProto[]
    end
end
function Base.getproperty(obj::ServiceDescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :method
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{MethodDescriptorProto}
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::ServiceOptions
    else
        getfield(obj, name)
    end
end

mutable struct SourceCodeInfo_Location <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function SourceCodeInfo_Location(; kwargs...)
        obj = new(meta(SourceCodeInfo_Location), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct SourceCodeInfo_Location
const __meta_SourceCodeInfo_Location = Ref{ProtoMeta}()
function meta(::Type{SourceCodeInfo_Location})
    ProtoBuf.metalock() do
        if !isassigned(__meta_SourceCodeInfo_Location)
            __meta_SourceCodeInfo_Location[] = target = ProtoMeta(SourceCodeInfo_Location)
            fnum = Int[1,2,3,4,6]
            pack = Symbol[:path,:span]
            allflds = Pair{Symbol,Union{Type,String}}[:path => Base.Vector{Int32}, :span => Base.Vector{Int32}, :leading_comments => AbstractString, :trailing_comments => AbstractString, :leading_detached_comments => Base.Vector{AbstractString}]
            meta(target, SourceCodeInfo_Location, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, pack, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_SourceCodeInfo_Location[]
    end
end
function Base.getproperty(obj::SourceCodeInfo_Location, name::Symbol)
    if name === :path
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Int32}
    elseif name === :span
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Int32}
    elseif name === :leading_comments
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :trailing_comments
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :leading_detached_comments
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{AbstractString}
    else
        getfield(obj, name)
    end
end

mutable struct SourceCodeInfo <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function SourceCodeInfo(; kwargs...)
        obj = new(meta(SourceCodeInfo), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct SourceCodeInfo
const __meta_SourceCodeInfo = Ref{ProtoMeta}()
function meta(::Type{SourceCodeInfo})
    ProtoBuf.metalock() do
        if !isassigned(__meta_SourceCodeInfo)
            __meta_SourceCodeInfo[] = target = ProtoMeta(SourceCodeInfo)
            allflds = Pair{Symbol,Union{Type,String}}[:location => Base.Vector{SourceCodeInfo_Location}]
            meta(target, SourceCodeInfo, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_SourceCodeInfo[]
    end
end
function Base.getproperty(obj::SourceCodeInfo, name::Symbol)
    if name === :location
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{SourceCodeInfo_Location}
    else
        getfield(obj, name)
    end
end

mutable struct FileDescriptorProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FileDescriptorProto(; kwargs...)
        obj = new(meta(FileDescriptorProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FileDescriptorProto
const __meta_FileDescriptorProto = Ref{ProtoMeta}()
function meta(::Type{FileDescriptorProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FileDescriptorProto)
            __meta_FileDescriptorProto[] = target = ProtoMeta(FileDescriptorProto)
            fnum = Int[1,2,3,10,11,4,5,6,7,8,9,12]
            allflds = Pair{Symbol,Union{Type,String}}[:name => AbstractString, :package => AbstractString, :dependency => Base.Vector{AbstractString}, :public_dependency => Base.Vector{Int32}, :weak_dependency => Base.Vector{Int32}, :message_type => Base.Vector{DescriptorProto}, :enum_type => Base.Vector{EnumDescriptorProto}, :service => Base.Vector{ServiceDescriptorProto}, :extension => Base.Vector{FieldDescriptorProto}, :options => FileOptions, :source_code_info => SourceCodeInfo, :syntax => AbstractString]
            meta(target, FileDescriptorProto, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FileDescriptorProto[]
    end
end
function Base.getproperty(obj::FileDescriptorProto, name::Symbol)
    if name === :name
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :package
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :dependency
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{AbstractString}
    elseif name === :public_dependency
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Int32}
    elseif name === :weak_dependency
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Int32}
    elseif name === :message_type
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{DescriptorProto}
    elseif name === :enum_type
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{EnumDescriptorProto}
    elseif name === :service
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{ServiceDescriptorProto}
    elseif name === :extension
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{FieldDescriptorProto}
    elseif name === :options
        return (obj.__protobuf_jl_internal_values[name])::FileOptions
    elseif name === :source_code_info
        return (obj.__protobuf_jl_internal_values[name])::SourceCodeInfo
    elseif name === :syntax
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    else
        getfield(obj, name)
    end
end

mutable struct FileDescriptorSet <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function FileDescriptorSet(; kwargs...)
        obj = new(meta(FileDescriptorSet), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct FileDescriptorSet
const __meta_FileDescriptorSet = Ref{ProtoMeta}()
function meta(::Type{FileDescriptorSet})
    ProtoBuf.metalock() do
        if !isassigned(__meta_FileDescriptorSet)
            __meta_FileDescriptorSet[] = target = ProtoMeta(FileDescriptorSet)
            allflds = Pair{Symbol,Union{Type,String}}[:file => Base.Vector{FileDescriptorProto}]
            meta(target, FileDescriptorSet, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_FileDescriptorSet[]
    end
end
function Base.getproperty(obj::FileDescriptorSet, name::Symbol)
    if name === :file
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{FileDescriptorProto}
    else
        getfield(obj, name)
    end
end

mutable struct GeneratedCodeInfo_Annotation <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function GeneratedCodeInfo_Annotation(; kwargs...)
        obj = new(meta(GeneratedCodeInfo_Annotation), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct GeneratedCodeInfo_Annotation
const __meta_GeneratedCodeInfo_Annotation = Ref{ProtoMeta}()
function meta(::Type{GeneratedCodeInfo_Annotation})
    ProtoBuf.metalock() do
        if !isassigned(__meta_GeneratedCodeInfo_Annotation)
            __meta_GeneratedCodeInfo_Annotation[] = target = ProtoMeta(GeneratedCodeInfo_Annotation)
            pack = Symbol[:path]
            allflds = Pair{Symbol,Union{Type,String}}[:path => Base.Vector{Int32}, :source_file => AbstractString, :_begin => Int32, :_end => Int32]
            meta(target, GeneratedCodeInfo_Annotation, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, pack, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_GeneratedCodeInfo_Annotation[]
    end
end
function Base.getproperty(obj::GeneratedCodeInfo_Annotation, name::Symbol)
    if name === :path
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{Int32}
    elseif name === :source_file
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :_begin
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :_end
        return (obj.__protobuf_jl_internal_values[name])::Int32
    else
        getfield(obj, name)
    end
end

mutable struct GeneratedCodeInfo <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function GeneratedCodeInfo(; kwargs...)
        obj = new(meta(GeneratedCodeInfo), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct GeneratedCodeInfo
const __meta_GeneratedCodeInfo = Ref{ProtoMeta}()
function meta(::Type{GeneratedCodeInfo})
    ProtoBuf.metalock() do
        if !isassigned(__meta_GeneratedCodeInfo)
            __meta_GeneratedCodeInfo[] = target = ProtoMeta(GeneratedCodeInfo)
            allflds = Pair{Symbol,Union{Type,String}}[:annotation => Base.Vector{GeneratedCodeInfo_Annotation}]
            meta(target, GeneratedCodeInfo, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_GeneratedCodeInfo[]
    end
end
function Base.getproperty(obj::GeneratedCodeInfo, name::Symbol)
    if name === :annotation
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{GeneratedCodeInfo_Annotation}
    else
        getfield(obj, name)
    end
end

export FileDescriptorSet, FileDescriptorProto, DescriptorProto_ExtensionRange, DescriptorProto_ReservedRange, DescriptorProto, ExtensionRangeOptions, FieldDescriptorProto_Type, FieldDescriptorProto_Label, FieldDescriptorProto, OneofDescriptorProto, EnumDescriptorProto_EnumReservedRange, EnumDescriptorProto, EnumValueDescriptorProto, ServiceDescriptorProto, MethodDescriptorProto, FileOptions_OptimizeMode, FileOptions, MessageOptions, FieldOptions_CType, FieldOptions_JSType, FieldOptions, OneofOptions, EnumOptions, EnumValueOptions, ServiceOptions, MethodOptions_IdempotencyLevel, MethodOptions, UninterpretedOption_NamePart, UninterpretedOption, SourceCodeInfo_Location, SourceCodeInfo, GeneratedCodeInfo_Annotation, GeneratedCodeInfo


text:
using TopOptTools
using Test

@testset "TopOptTools.jl" begin
    # Write your tests here.
end