├── test ├── test_helper.exs └── pprof_test.exs ├── .formatter.exs ├── lib ├── pprof │ ├── servers │ │ ├── utils.ex │ │ └── profile.ex │ ├── application.ex │ ├── builder │ │ ├── string_id.ex │ │ ├── function_id.ex │ │ ├── location_id.ex │ │ ├── profile.ex │ │ └── build.ex │ ├── router.ex │ └── proto │ │ ├── profile.proto │ │ └── profile.pb.ex └── pprof.ex ├── .gitignore ├── LICENSE ├── mix.exs ├── README.md └── mix.lock /test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /test/pprof_test.exs: -------------------------------------------------------------------------------- 1 | defmodule PprofTest do 2 | use ExUnit.Case 3 | doctest Pprof 4 | 5 | test "greets the world" do 6 | assert Pprof.hello() == :world 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/pprof/servers/utils.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Servers.Utils do 2 | alias Pprof.Builder.FunctionId 3 | alias Pprof.Builder.LocationId 4 | alias Pprof.Builder.StringId 5 | alias Pprof.Builder.Profile 6 | 7 | def flush_agents() do 8 | FunctionId.flush(FunctionId) 9 | LocationId.flush(LocationId) 10 | StringId.flush(StringId) 11 | Profile.flush(Profile) 12 | end 13 | 14 | def fprof(_pid, msecs) do 15 | :fprof.trace([:start, verbose: true, procs: :all]) 16 | Process.sleep(msecs) 17 | :fprof.trace(:stop) 18 | :fprof.profile() 19 | :fprof.analyse({:dest, '/tmp/profile.fprof'}) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | pprof-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | 28 | .idea 29 | 30 | .elixir_ls 31 | 32 | /config/ 33 | -------------------------------------------------------------------------------- /lib/pprof/application.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Application do 2 | # See https://hexdocs.pm/elixir/Application.html 3 | # for more information on OTP Applications 4 | @moduledoc false 5 | 6 | use Application 7 | 8 | @impl true 9 | def start(_type, _args) do 10 | port = Application.fetch_env!(:pprof, :port) 11 | 12 | children = [ 13 | {Pprof.Servers.Profile, []}, 14 | {Plug.Cowboy, scheme: :http, plug: Pprof.Router, port: port, compress: true} 15 | # Starts a worker by calling: Pprof.Worker.start_link(arg) 16 | # {Pprof.Worker, arg} 17 | ] 18 | 19 | # See https://hexdocs.pm/elixir/Supervisor.html 20 | # for other strategies and supported options 21 | opts = [strategy: :one_for_one, name: Pprof.Supervisor] 22 | Supervisor.start_link(children, opts) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/pprof/builder/string_id.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Builder.StringId do 2 | use Agent 3 | 4 | @doc """ 5 | Starts a new bucket. 6 | """ 7 | def start_link(_opts) do 8 | Agent.start_link(fn -> %{} end, name: __MODULE__) 9 | end 10 | 11 | @doc """ 12 | Gets a value from the `bucket` by `key`. 13 | """ 14 | def get(bucket, key) do 15 | Agent.get(bucket, &Map.get(&1, key)) 16 | end 17 | 18 | @doc """ 19 | Puts the `value` for the given `key` in the `bucket`. 20 | """ 21 | def put(bucket, key, value) do 22 | Agent.update(bucket, &Map.put(&1, key, value)) 23 | end 24 | 25 | def flush(bucket) do 26 | Agent.update(bucket, fn _ -> %{} end) 27 | end 28 | 29 | @doc """ 30 | Get the size of `bucket`. 31 | """ 32 | def size(bucket) do 33 | Agent.get(bucket, &Enum.count/1) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/pprof/builder/function_id.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Builder.FunctionId do 2 | use Agent 3 | 4 | @doc """ 5 | Starts a new bucket. 6 | """ 7 | def start_link(_opts) do 8 | Agent.start_link(fn -> %{} end, name: __MODULE__) 9 | end 10 | 11 | @doc """ 12 | Gets a value from the `bucket` by `key`. 13 | """ 14 | def get(bucket, key) do 15 | Agent.get(bucket, &Map.get(&1, key)) 16 | end 17 | 18 | def get_all(bucket) do 19 | Agent.get(bucket, fn state -> state end) 20 | end 21 | 22 | @doc """ 23 | Puts the `value` for the given `key` in the `bucket`. 24 | """ 25 | def put(bucket, key, value) do 26 | Agent.update(bucket, &Map.put(&1, key, value)) 27 | end 28 | 29 | def flush(bucket) do 30 | Agent.update(bucket, fn _ -> %{} end) 31 | end 32 | 33 | @doc """ 34 | Get the size of `bucket`. 35 | """ 36 | def size(bucket) do 37 | Agent.get(bucket, &Enum.count/1) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/pprof/builder/location_id.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Builder.LocationId do 2 | use Agent 3 | 4 | @doc """ 5 | Starts a new bucket. 6 | """ 7 | def start_link(_opts) do 8 | Agent.start_link(fn -> %{} end, name: __MODULE__) 9 | end 10 | 11 | @doc """ 12 | Gets a value from the `bucket` by `key`. 13 | """ 14 | def get(bucket, key) do 15 | Agent.get(bucket, &Map.get(&1, key)) 16 | end 17 | 18 | def get_all(bucket) do 19 | Agent.get(bucket, fn state -> state end) 20 | end 21 | 22 | @doc """ 23 | Puts the `value` for the given `key` in the `bucket`. 24 | """ 25 | def put(bucket, key, value) do 26 | Agent.update(bucket, &Map.put(&1, key, value)) 27 | end 28 | 29 | def flush(bucket) do 30 | Agent.update(bucket, fn _ -> %{} end) 31 | end 32 | 33 | @doc """ 34 | Get the size of `bucket`. 35 | """ 36 | def size(bucket) do 37 | Agent.get(bucket, &Enum.count/1) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/pprof/builder/profile.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Builder.Profile do 2 | use Agent 3 | 4 | @doc """ 5 | Starts a new bucket. 6 | """ 7 | def start_link(_opts) do 8 | Agent.start_link(fn -> %Perftools.Profiles.Profile{} end, name: __MODULE__) 9 | end 10 | 11 | @doc """ 12 | Gets a value from the `bucket` by `key`. 13 | """ 14 | def get(bucket, key) do 15 | Agent.get(bucket, &Map.get(&1, key)) 16 | end 17 | 18 | def get_all(bucket) do 19 | Agent.get(bucket, fn state -> state end) 20 | end 21 | 22 | @doc """ 23 | Puts the `value` for the given `key` in the `bucket`. 24 | """ 25 | def put(bucket, key, value) do 26 | Agent.update(bucket, &Map.put(&1, key, value)) 27 | end 28 | 29 | def flush(bucket) do 30 | Agent.update(bucket, fn _ -> %Perftools.Profiles.Profile{} end) 31 | end 32 | 33 | @doc """ 34 | Get the size of `bucket`. 35 | """ 36 | def size(bucket) do 37 | Agent.get(bucket, &Enum.count/1) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/pprof/servers/profile.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Servers.Profile do 2 | use GenServer 3 | 4 | alias Pprof.Builder.FunctionId 5 | alias Pprof.Builder.LocationId 6 | alias Pprof.Builder.StringId 7 | alias Pprof.Builder.Profile 8 | alias Pprof.Servers.Utils 9 | 10 | def start_link(_opts) do 11 | GenServer.start_link(__MODULE__, :init, name: __MODULE__) 12 | end 13 | 14 | @impl true 15 | def init(:init) do 16 | FunctionId.start_link([]) 17 | LocationId.start_link([]) 18 | StringId.start_link([]) 19 | Profile.start_link([]) 20 | 21 | {:ok, :init} 22 | end 23 | 24 | @impl true 25 | def handle_call({:profile, type, pid, msec}, _, state) do 26 | check_pid = if pid == nil, do: self(), else: pid 27 | 28 | case type do 29 | "fprof" -> 30 | Utils.fprof(check_pid, msec) 31 | Utils.flush_agents() 32 | 33 | {:reply, {:ok, nil}, state} 34 | 35 | _ -> 36 | {:reply, {:error, "type is not supported"}, state} 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Doğukan Zorlu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Pprof.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :pprof, 7 | version: "0.1.0", 8 | elixir: "~> 1.14", 9 | start_permanent: Mix.env() == :prod, 10 | description: description(), 11 | package: package(), 12 | deps: deps() 13 | ] 14 | end 15 | 16 | def description do 17 | """ 18 | `Pprof` serves via its HTTP server fprof profiling data in the format expected by the pprof visualization tools for Elixir. 19 | """ 20 | end 21 | 22 | defp package do 23 | [ 24 | files: ["lib", "mix.exs", "README.md"], 25 | maintainers: ["Dogukan Zorlu"], 26 | licenses: ["MIT"], 27 | links: %{"GitHub" => "https://github.com/dogukanzorlu/pprof", 28 | "Docs" => "https://hexdocs.pm/pprof/"} 29 | ] 30 | end 31 | 32 | # Run "mix help compile.app" to learn about applications. 33 | def application do 34 | [ 35 | extra_applications: [:logger, :tools], 36 | mod: {Pprof.Application, []} 37 | ] 38 | end 39 | 40 | # Run "mix help deps" to learn about dependencies. 41 | defp deps do 42 | [ 43 | {:plug_cowboy, "~> 2.0"}, 44 | {:protox, "~> 1.6"}, 45 | {:jason, "~> 1.2"}, 46 | {:ex_doc, "~> 0.11", only: :dev}, 47 | {:earmark, "~> 0.1", only: :dev}, 48 | {:dialyxir, "~> 0.3", only: [:dev]} 49 | # {:dep_from_hexpm, "~> 0.3.0"}, 50 | # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} 51 | ] 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/pprof/router.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Router do 2 | use Plug.Router 3 | use Plug.ErrorHandler 4 | 5 | plug(Plug.Parsers, parsers: [:urlencoded, :multipart], pass: ["text/*"]) 6 | 7 | plug(Plug.Static, 8 | at: "./priv/static", 9 | from: "./priv/static", 10 | gzip: true 11 | ) 12 | 13 | plug(:match) 14 | plug(:dispatch) 15 | 16 | get "/pprof" do 17 | send_resp(conn, 200, "Welcome") 18 | end 19 | 20 | get "/debug/pprof/profile" do 21 | duration = conn.params["seconds"] 22 | pid = conn.params["pid"] 23 | type = conn.params["type"] 24 | 25 | msec = if duration == nil, do: 3000, else: String.to_integer(conn.params["seconds"]) * 1000 26 | 27 | {reply, res} = GenServer.call(Pprof.Servers.Profile, {:profile, type, pid, msec}, msec + 1000) 28 | 29 | case reply do 30 | :ok -> 31 | resp = Pprof.Builder.Build.builder(msec) 32 | status = 200 33 | 34 | conn 35 | |> put_resp_header("Content-Disposition", "attachment; filename=profile.pb.gz") 36 | |> put_resp_header("Content-Type", "application/octet-stream") 37 | |> put_resp_header("X-Content-Type-Options", "nosniff") 38 | |> send_resp(status, resp) 39 | 40 | _ -> 41 | resp = res 42 | status = 500 43 | 44 | conn 45 | |> send_resp(status, resp) 46 | end 47 | end 48 | 49 | match _ do 50 | send_resp(conn, 404, "Oops!") 51 | end 52 | 53 | @impl Plug.ErrorHandler 54 | def handle_errors(conn, %{kind: _kind, reason: _reason, stack: _stack}) do 55 | send_resp(conn, conn.status, "Something went wrong") 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/pprof.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof do 2 | @moduledoc """ 3 | `Pprof` serves via its HTTP server fprof profiling data in the format expected by the pprof visualization tools for Elixir. 4 | 5 | `Pprof` basically uses erlang [:fprof](https://www.erlang.org/doc/man/fprof.html) and generates meaningful pprof data from noisy data of fprof profile. 6 | 7 | 8 | # Aim 9 | The observation and profiling culture of erlang and elixir is different from other languages. 10 | Elixir/Erlang runs on a virtual machine (a.k.a beam) and each block of code represents a process. 11 | Erlang provides many tools internally for monitoring abstracted processes and processes dependent functions. 12 | This library produces as meaningful pprof output as possible using the built-in Erlang profiling tools. Thus, it tries to spread the Erlang/Elixir observability with pprof-based ad-hoc profiling tools. 13 | 14 | # A few important things 15 | 16 | - This library an experimental and still under development, a library that needs to be careful to use on the production line. 17 | - The accuracy of the outputs has been proven by testing with cross-tools. But this alpha version does not offer a full pprof service. 18 | - fprof significantly slows down the application it is running on. It monitors all processes and collects their tracing data. 19 | Therefore, even a 10-second data collection in large-scale applications can mean GBs of data. 20 | It is recommended that the scrape seconds do not exceed 5 in order not to get lost in the abundance of data. More information: [:fprof](https://www.erlang.org/doc/man/fprof.html) 21 | 22 | 23 | # Installation and Usage 24 | 25 | ## Installation 26 | 27 | def deps do 28 | [ 29 | {:pprof, "~> 0.1.0"} 30 | ] 31 | end 32 | 33 | After: 34 | $ mix deps.get 35 | 36 | ## Usage 37 | 38 | Add pprof config your config file like this: 39 | 40 | config :pprof, :port, 8080 41 | 42 | You can use with go pprof: 43 | 44 | go tool pprof http://localhost:8080/debug/pprof/profile?seconds=5&type=fprof 45 | 46 | Also using with [Parca](https://github.com/parca-dev/parca) add configure in parca.yaml: 47 | # params: 48 | # type: [ 'fprof' ] 49 | 50 | # Contributing 51 | 52 | If you are an expert in elixir or erlang and want to contribute, please feel free. Who can say no to better written or more performant code? Thanks in advance for helping and teaching me so much. 53 | # License 54 | 55 | pprof is released under the [MIT License](https://opensource.org/licenses/MIT). 56 | """ 57 | end 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pprof 2 | `Pprof` serves via its HTTP server fprof profiling data in the format expected by the pprof visualization tools for Elixir. 3 | 4 | `Pprof` basically uses erlang [:fprof](https://www.erlang.org/doc/man/fprof.html) and generates meaningful pprof data from noisy data of fprof profile. 5 | 6 | # Table of Contents 7 | 8 | * [Documentation](#documentation) 9 | * [Aim](#aim) 10 | * [A few important things](#a-few-important-things) 11 | * [Installation and Usage](#installation-and-usage) 12 | * [Installation](#installation) 13 | * [Usage](#usage) 14 | * [TODO](#todo) 15 | * [Contributing](#contributing) 16 | * [License](#license) 17 | 18 | # Documentation 19 | Hex documentation: [Pprof](https://hexdocs.pm/pprof/0.1.0/Pprof.html) 20 | 21 | # Aim 22 | The observation and profiling culture of erlang and elixir is different from other languages. 23 | Elixir/Erlang runs on a virtual machine (a.k.a beam) and each block of code represents a process. 24 | Erlang provides many tools internally for monitoring abstracted processes and processes dependent functions. 25 | This library produces as meaningful pprof output as possible using the built-in Erlang profiling tools. Thus, it tries to spread the Erlang/Elixir observability with pprof-based ad-hoc profiling tools. 26 | 27 | # A few important things 28 | 29 | - This library an experimental and still under development, a library that needs to be careful to use on the production line. 30 | - The accuracy of the outputs has been proven by testing with cross-tools. But this alpha version does not offer a full pprof service. 31 | - fprof significantly slows down the application it is running on. It monitors all processes and collects their tracing data. 32 | Therefore, even a 10-second data collection in large-scale applications can mean GBs of data. 33 | It is recommended that the scrape seconds do not exceed 5 in order not to get lost in the abundance of data. More information: [:fprof](https://www.erlang.org/doc/man/fprof.html) 34 | 35 | 36 | # Installation and Usage 37 | 38 | ## Installation 39 | 40 | ```elixir 41 | def deps do 42 | [ 43 | {:pprof, "~> 0.1.0"} 44 | ] 45 | end 46 | ``` 47 | 48 | After: 49 | ```bash 50 | $ mix deps.get 51 | ``` 52 | 53 | ## Usage 54 | 55 | Add pprof config your config file like this: 56 | ```elixir 57 | config :pprof, :port, 8080 58 | ``` 59 | 60 | You can use with go pprof: 61 | ```bash 62 | $ go tool pprof http://localhost:8080/debug/pprof/profile?seconds=5&type=fprof 63 | 64 | ``` 65 | Also using with [Parca](https://github.com/parca-dev/parca) add configure in parca.yaml: 66 | ```yaml 67 | # params: 68 | # type: [ 'fprof' ] 69 | ``` 70 | 71 | # TODO 72 | - [x] :fprof support 73 | - [ ] :eprof support 74 | - [ ] :cprof support 75 | - [ ] mapping support 76 | - [ ] alloc endpoint 77 | - [ ] heap endpoint 78 | - [ ] processes monitoring(goroutine) endpoint 79 | - [ ] building test env 80 | - [ ] converting erlang stack 81 | 82 | # Contributing 83 | 84 | If you are an expert in elixir or erlang and want to contribute, please feel free. Who can say no to better written or more performant code? Thanks in advance for helping and teaching me so much. 85 | 86 | # License 87 | 88 | pprof is released under the [MIT License](https://opensource.org/licenses/MIT). 89 | -------------------------------------------------------------------------------- /lib/pprof/builder/build.ex: -------------------------------------------------------------------------------- 1 | defmodule Pprof.Builder.Build do 2 | alias Pprof.Builder.FunctionId 3 | alias Pprof.Builder.LocationId 4 | alias Pprof.Builder.StringId 5 | alias Pprof.Builder.Profile 6 | 7 | def builder(duration) do 8 | {_, terms} = :file.consult('/tmp/profile.fprof') 9 | res = process_terms(terms, duration) 10 | 11 | case res do 12 | {:process_terms, resp} -> 13 | resp 14 | end 15 | end 16 | 17 | def process_terms([], _opts) do 18 | {:ok, iodata} = Protox.encode(Profile.get_all(Profile)) 19 | compressed = :zlib.gzip(iodata) 20 | {:process_terms, compressed} 21 | end 22 | 23 | def process_terms([{_analysis_options, _} | rest], duration) do 24 | get_string_id("") 25 | 26 | Profile.put(Profile, :period_type, %Perftools.Profiles.ValueType{ 27 | type: get_string_id("CPU"), 28 | unit: get_string_id("nanoseconds") 29 | }) 30 | 31 | Profile.put(Profile, :period, 10_000 * 1000 * 1000) 32 | Profile.put(Profile, :time_nanos, :os.system_time(:nanosecond)) 33 | Profile.put(Profile, :duration_nanos, duration * 1000 * 1000) 34 | 35 | set_list_to_profile(:sample_type, %Perftools.Profiles.ValueType{ 36 | type: get_string_id("sample"), 37 | unit: get_string_id("count") 38 | }) 39 | 40 | set_list_to_profile(:sample_type, %Perftools.Profiles.ValueType{ 41 | type: get_string_id("CPU"), 42 | unit: get_string_id("nanoseconds") 43 | }) 44 | 45 | process_terms(rest, duration) 46 | end 47 | 48 | def process_terms([[{pid, _Cnt, _Acc, _Own} | _T] | rest], duration) when is_list(pid) do 49 | process_terms(rest, duration) 50 | end 51 | 52 | def process_terms([list | rest], duration) when is_list(list) do 53 | process_terms(rest, duration) 54 | end 55 | 56 | def process_terms([entry | rest], duration) do 57 | process_entry(entry) 58 | process_terms(rest, duration) 59 | end 60 | 61 | def process_entry({_CallingList, actual, called_list}) do 62 | if(Enum.count(called_list) != 0) do 63 | merged_list = 64 | Enum.concat([actual], called_list) 65 | |> Enum.reverse() 66 | 67 | time = actual_time(merged_list |> List.first()) 68 | 69 | loc_ids = 70 | merged_list 71 | |> Enum.map(fn {mod, _, _, _} -> 72 | func_id = get_function_id("#{inspect(mod)}", to_string(inspect(mod))) 73 | ids = get_location_id(func_id, 1) 74 | ids 75 | end) 76 | 77 | set_list_to_profile(:sample, %Perftools.Profiles.Sample{ 78 | location_id: loc_ids, 79 | value: [1, time] 80 | }) 81 | end 82 | end 83 | 84 | def actual_time({:suspend, _, acc, _}) do 85 | Kernel.trunc(acc * 1000 * 1000) 86 | end 87 | 88 | def actual_time({_, _, _, own}) do 89 | Kernel.trunc(own * 1000 * 1000) 90 | end 91 | 92 | def get_string_id(value) do 93 | string_id = StringId.get(StringId, value) 94 | 95 | case string_id do 96 | nil -> 97 | size = StringId.size(StringId) 98 | 99 | StringId.put(StringId, value, size) 100 | 101 | set_list_to_profile(:string_table, value) 102 | 103 | size 104 | 105 | _ -> 106 | string_id 107 | end 108 | end 109 | 110 | def get_function_id(name, filename) do 111 | name_id = get_string_id(name) 112 | filename_id = get_string_id(filename) 113 | 114 | function = {name_id, filename_id} 115 | func_id = FunctionId.get(FunctionId, function) 116 | 117 | case func_id do 118 | nil -> 119 | size = FunctionId.size(FunctionId) + 1 120 | 121 | FunctionId.put(FunctionId, function, size) 122 | 123 | value = %Perftools.Profiles.Function{name: name_id, filename: filename_id, id: size} 124 | set_list_to_profile(:function, value) 125 | 126 | size 127 | 128 | _ -> 129 | func_id 130 | end 131 | end 132 | 133 | def get_location_id(func_id, line) do 134 | location = {func_id, line} 135 | location_id = LocationId.get(LocationId, location) 136 | 137 | case location_id do 138 | nil -> 139 | size = LocationId.size(LocationId) + 1 140 | 141 | LocationId.put(LocationId, location, size) 142 | 143 | line_perf = %Perftools.Profiles.Line{function_id: func_id, line: line} 144 | value = %Perftools.Profiles.Location{id: size, line: [line_perf]} 145 | set_list_to_profile(:location, value) 146 | 147 | size 148 | 149 | _ -> 150 | location_id 151 | end 152 | end 153 | 154 | defp set_list_to_profile(key, value) do 155 | current_value = Profile.get(Profile, key) 156 | 157 | Profile.put(Profile, key, Enum.concat(current_value, [value])) 158 | end 159 | end 160 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{ 2 | "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, 3 | "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, 4 | "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, 5 | "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, 6 | "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"}, 7 | "earmark": {:hex, :earmark, "0.2.1", "ba6d26ceb16106d069b289df66751734802777a3cbb6787026dd800ffeb850f3", [:mix], [], "hexpm", "c86afb8d22a5aa8315afd4257c7512011c0c9a48b0fea43af7612836b958098b"}, 8 | "earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"}, 9 | "ex_doc": {:hex, :ex_doc, "0.29.1", "b1c652fa5f92ee9cf15c75271168027f92039b3877094290a75abcaac82a9f77", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "b7745fa6374a36daf484e2a2012274950e084815b936b1319aeebcf7809574f6"}, 10 | "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, 11 | "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, 12 | "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, 13 | "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, 14 | "mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"}, 15 | "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, 16 | "plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"}, 17 | "plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"}, 18 | "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, 19 | "protox": {:hex, :protox, "1.7.2", "ed800ae523fa7b7e68a411645922c8061daacfa57aacff2a38d63aa092304a8c", [:mix], [{:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "02230413186776adac7d05237e17e4d20e69b270ae086fab6f1fffda8094d9b0"}, 20 | "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, 21 | "telemetry": {:hex, :telemetry, "1.2.0", "a8ce551485a9a3dac8d523542de130eafd12e40bbf76cf0ecd2528f24e812a44", [:rebar3], [], "hexpm", "1427e73667b9a2002cf1f26694c422d5c905df889023903c4518921d53e3e883"}, 22 | } 23 | -------------------------------------------------------------------------------- /lib/pprof/proto/profile.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Profile is a common stacktrace profile format. 16 | // 17 | // Measurements represented with this format should follow the 18 | // following conventions: 19 | // 20 | // - Consumers should treat unset optional fields as if they had been 21 | // set with their default value. 22 | // 23 | // - When possible, measurements should be stored in "unsampled" form 24 | // that is most useful to humans. There should be enough 25 | // information present to determine the original sampled values. 26 | // 27 | // - On-disk, the serialized proto must be gzip-compressed. 28 | // 29 | // - The profile is represented as a set of samples, where each sample 30 | // references a sequence of locations, and where each location belongs 31 | // to a mapping. 32 | // - There is a N->1 relationship from sample.location_id entries to 33 | // locations. For every sample.location_id entry there must be a 34 | // unique Location with that id. 35 | // - There is an optional N->1 relationship from locations to 36 | // mappings. For every nonzero Location.mapping_id there must be a 37 | // unique Mapping with that id. 38 | 39 | syntax = "proto3"; 40 | 41 | package perftools.profiles; 42 | 43 | option java_package = "com.google.perftools.profiles"; 44 | option java_outer_classname = "ProfileProto"; 45 | 46 | message Profile { 47 | // A description of the samples associated with each Sample.value. 48 | // For a cpu profile this might be: 49 | // [["cpu","nanoseconds"]] or [["wall","seconds"]] or [["syscall","count"]] 50 | // For a heap profile, this might be: 51 | // [["allocations","count"], ["space","bytes"]], 52 | // If one of the values represents the number of events represented 53 | // by the sample, by convention it should be at index 0 and use 54 | // sample_type.unit == "count". 55 | repeated ValueType sample_type = 1; 56 | // The set of samples recorded in this profile. 57 | repeated Sample sample = 2; 58 | // Mapping from address ranges to the image/binary/library mapped 59 | // into that address range. mapping[0] will be the main binary. 60 | repeated Mapping mapping = 3; 61 | // Useful program location 62 | repeated Location location = 4; 63 | // Functions referenced by locations 64 | repeated Function function = 5; 65 | // A common table for strings referenced by various messages. 66 | // string_table[0] must always be "". 67 | repeated string string_table = 6; 68 | // frames with Function.function_name fully matching the following 69 | // regexp will be dropped from the samples, along with their successors. 70 | int64 drop_frames = 7; // Index into string table. 71 | // frames with Function.function_name fully matching the following 72 | // regexp will be kept, even if it matches drop_frames. 73 | int64 keep_frames = 8; // Index into string table. 74 | 75 | // The following fields are informational, do not affect 76 | // interpretation of results. 77 | 78 | // Time of collection (UTC) represented as nanoseconds past the epoch. 79 | int64 time_nanos = 9; 80 | // Duration of the profile, if a duration makes sense. 81 | int64 duration_nanos = 10; 82 | // The kind of events between sampled ocurrences. 83 | // e.g [ "cpu","cycles" ] or [ "heap","bytes" ] 84 | ValueType period_type = 11; 85 | // The number of events between sampled occurrences. 86 | int64 period = 12; 87 | // Freeform text associated to the profile. 88 | repeated int64 comment = 13; // Indices into string table. 89 | // Index into the string table of the type of the preferred sample 90 | // value. If unset, clients should default to the last sample value. 91 | int64 default_sample_type = 14; 92 | } 93 | 94 | // ValueType describes the semantics and measurement units of a value. 95 | message ValueType { 96 | int64 type = 1; // Index into string table. 97 | int64 unit = 2; // Index into string table. 98 | } 99 | 100 | // Each Sample records values encountered in some program 101 | // context. The program context is typically a stack trace, perhaps 102 | // augmented with auxiliary information like the thread-id, some 103 | // indicator of a higher level request being handled etc. 104 | message Sample { 105 | // The ids recorded here correspond to a Profile.location.id. 106 | // The leaf is at location_id[0]. 107 | repeated uint64 location_id = 1; 108 | // The type and unit of each value is defined by the corresponding 109 | // entry in Profile.sample_type. All samples must have the same 110 | // number of values, the same as the length of Profile.sample_type. 111 | // When aggregating multiple samples into a single sample, the 112 | // result has a list of values that is the element-wise sum of the 113 | // lists of the originals. 114 | repeated int64 value = 2; 115 | // label includes additional context for this sample. It can include 116 | // things like a thread id, allocation size, etc 117 | repeated Label label = 3; 118 | } 119 | 120 | message Label { 121 | int64 key = 1; // Index into string table 122 | 123 | // At most one of the following must be present 124 | int64 str = 2; // Index into string table 125 | int64 num = 3; 126 | 127 | // Should only be present when num is present. 128 | // Specifies the units of num. 129 | // Use arbitrary string (for example, "requests") as a custom count unit. 130 | // If no unit is specified, consumer may apply heuristic to deduce the unit. 131 | // Consumers may also interpret units like "bytes" and "kilobytes" as memory 132 | // units and units like "seconds" and "nanoseconds" as time units, 133 | // and apply appropriate unit conversions to these. 134 | int64 num_unit = 4; // Index into string table 135 | } 136 | 137 | message Mapping { 138 | // Unique nonzero id for the mapping. 139 | uint64 id = 1; 140 | // Address at which the binary (or DLL) is loaded into memory. 141 | uint64 memory_start = 2; 142 | // The limit of the address range occupied by this mapping. 143 | uint64 memory_limit = 3; 144 | // Offset in the binary that corresponds to the first mapped address. 145 | uint64 file_offset = 4; 146 | // The object this entry is loaded from. This can be a filename on 147 | // disk for the main binary and shared libraries, or virtual 148 | // abstractions like "[vdso]". 149 | int64 filename = 5; // Index into string table 150 | // A string that uniquely identifies a particular program version 151 | // with high probability. E.g., for binaries generated by GNU tools, 152 | // it could be the contents of the .note.gnu.build-id field. 153 | int64 build_id = 6; // Index into string table 154 | 155 | // The following fields indicate the resolution of symbolic info. 156 | bool has_functions = 7; 157 | bool has_filenames = 8; 158 | bool has_line_numbers = 9; 159 | bool has_inline_frames = 10; 160 | } 161 | 162 | // Describes function and line table debug information. 163 | message Location { 164 | // Unique nonzero id for the location. A profile could use 165 | // instruction addresses or any integer sequence as ids. 166 | uint64 id = 1; 167 | // The id of the corresponding profile.Mapping for this location. 168 | // It can be unset if the mapping is unknown or not applicable for 169 | // this profile type. 170 | uint64 mapping_id = 2; 171 | // The instruction address for this location, if available. It 172 | // should be within [Mapping.memory_start...Mapping.memory_limit] 173 | // for the corresponding mapping. A non-leaf address may be in the 174 | // middle of a call instruction. It is up to display tools to find 175 | // the beginning of the instruction if necessary. 176 | uint64 address = 3; 177 | // Multiple line indicates this location has inlined functions, 178 | // where the last entry represents the caller into which the 179 | // preceding entries were inlined. 180 | // 181 | // E.g., if memcpy() is inlined into printf: 182 | // line[0].function_name == "memcpy" 183 | // line[1].function_name == "printf" 184 | repeated Line line = 4; 185 | // Provides an indication that multiple symbols map to this location's 186 | // address, for example due to identical code folding by the linker. In that 187 | // case the line information above represents one of the multiple 188 | // symbols. This field must be recomputed when the symbolization state of the 189 | // profile changes. 190 | bool is_folded = 5; 191 | } 192 | 193 | message Line { 194 | // The id of the corresponding profile.Function for this line. 195 | uint64 function_id = 1; 196 | // Line number in source code. 197 | int64 line = 2; 198 | } 199 | 200 | message Function { 201 | // Unique nonzero id for the function. 202 | uint64 id = 1; 203 | // Name of the function, in human-readable form if available. 204 | int64 name = 2; // Index into string table 205 | // Name of the function, as identified by the system. 206 | // For instance, it can be a C++ mangled name. 207 | int64 system_name = 3; // Index into string table 208 | // Source file containing the function. 209 | int64 filename = 4; // Index into string table 210 | // Line number in source file. 211 | int64 start_line = 5; 212 | } -------------------------------------------------------------------------------- /lib/pprof/proto/profile.pb.ex: -------------------------------------------------------------------------------- 1 | # credo:disable-for-this-file 2 | [ 3 | defmodule Perftools.Profiles.Function do 4 | @moduledoc false 5 | defstruct id: 0, name: 0, system_name: 0, filename: 0, start_line: 0, __uf__: [] 6 | 7 | ( 8 | ( 9 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 10 | def encode(msg) do 11 | try do 12 | {:ok, encode!(msg)} 13 | rescue 14 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 15 | end 16 | end 17 | 18 | @spec encode!(struct) :: iodata | no_return 19 | def encode!(msg) do 20 | [] 21 | |> encode_id(msg) 22 | |> encode_name(msg) 23 | |> encode_system_name(msg) 24 | |> encode_filename(msg) 25 | |> encode_start_line(msg) 26 | |> encode_unknown_fields(msg) 27 | end 28 | ) 29 | 30 | [] 31 | 32 | [ 33 | defp encode_id(acc, msg) do 34 | try do 35 | if msg.id == 0 do 36 | acc 37 | else 38 | [acc, "\b", Protox.Encode.encode_uint64(msg.id)] 39 | end 40 | rescue 41 | ArgumentError -> 42 | reraise Protox.EncodingError.new(:id, "invalid field value"), __STACKTRACE__ 43 | end 44 | end, 45 | defp encode_name(acc, msg) do 46 | try do 47 | if msg.name == 0 do 48 | acc 49 | else 50 | [acc, "\x10", Protox.Encode.encode_int64(msg.name)] 51 | end 52 | rescue 53 | ArgumentError -> 54 | reraise Protox.EncodingError.new(:name, "invalid field value"), __STACKTRACE__ 55 | end 56 | end, 57 | defp encode_system_name(acc, msg) do 58 | try do 59 | if msg.system_name == 0 do 60 | acc 61 | else 62 | [acc, "\x18", Protox.Encode.encode_int64(msg.system_name)] 63 | end 64 | rescue 65 | ArgumentError -> 66 | reraise Protox.EncodingError.new(:system_name, "invalid field value"), 67 | __STACKTRACE__ 68 | end 69 | end, 70 | defp encode_filename(acc, msg) do 71 | try do 72 | if msg.filename == 0 do 73 | acc 74 | else 75 | [acc, " ", Protox.Encode.encode_int64(msg.filename)] 76 | end 77 | rescue 78 | ArgumentError -> 79 | reraise Protox.EncodingError.new(:filename, "invalid field value"), __STACKTRACE__ 80 | end 81 | end, 82 | defp encode_start_line(acc, msg) do 83 | try do 84 | if msg.start_line == 0 do 85 | acc 86 | else 87 | [acc, "(", Protox.Encode.encode_int64(msg.start_line)] 88 | end 89 | rescue 90 | ArgumentError -> 91 | reraise Protox.EncodingError.new(:start_line, "invalid field value"), __STACKTRACE__ 92 | end 93 | end 94 | ] 95 | 96 | defp encode_unknown_fields(acc, msg) do 97 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 98 | case wire_type do 99 | 0 -> 100 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 101 | 102 | 1 -> 103 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 104 | 105 | 2 -> 106 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 107 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 108 | 109 | 5 -> 110 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 111 | end 112 | end) 113 | end 114 | ) 115 | 116 | ( 117 | ( 118 | @spec decode(binary) :: {:ok, struct} | {:error, any} 119 | def decode(bytes) do 120 | try do 121 | {:ok, decode!(bytes)} 122 | rescue 123 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 124 | {:error, e} 125 | end 126 | end 127 | 128 | ( 129 | @spec decode!(binary) :: struct | no_return 130 | def decode!(bytes) do 131 | parse_key_value(bytes, struct(Perftools.Profiles.Function)) 132 | end 133 | ) 134 | ) 135 | 136 | ( 137 | @spec parse_key_value(binary, struct) :: struct 138 | defp parse_key_value(<<>>, msg) do 139 | msg 140 | end 141 | 142 | defp parse_key_value(bytes, msg) do 143 | {field, rest} = 144 | case Protox.Decode.parse_key(bytes) do 145 | {0, _, _} -> 146 | raise %Protox.IllegalTagError{} 147 | 148 | {1, _, bytes} -> 149 | {value, rest} = Protox.Decode.parse_uint64(bytes) 150 | {[id: value], rest} 151 | 152 | {2, _, bytes} -> 153 | {value, rest} = Protox.Decode.parse_int64(bytes) 154 | {[name: value], rest} 155 | 156 | {3, _, bytes} -> 157 | {value, rest} = Protox.Decode.parse_int64(bytes) 158 | {[system_name: value], rest} 159 | 160 | {4, _, bytes} -> 161 | {value, rest} = Protox.Decode.parse_int64(bytes) 162 | {[filename: value], rest} 163 | 164 | {5, _, bytes} -> 165 | {value, rest} = Protox.Decode.parse_int64(bytes) 166 | {[start_line: value], rest} 167 | 168 | {tag, wire_type, rest} -> 169 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 170 | 171 | {[ 172 | {msg.__struct__.unknown_fields_name, 173 | [value | msg.__struct__.unknown_fields(msg)]} 174 | ], rest} 175 | end 176 | 177 | msg_updated = struct(msg, field) 178 | parse_key_value(rest, msg_updated) 179 | end 180 | ) 181 | 182 | [] 183 | ) 184 | 185 | ( 186 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 187 | def json_decode(input, opts \\ []) do 188 | try do 189 | {:ok, json_decode!(input, opts)} 190 | rescue 191 | e in Protox.JsonDecodingError -> {:error, e} 192 | end 193 | end 194 | 195 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 196 | def json_decode!(input, opts \\ []) do 197 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 198 | 199 | Protox.JsonDecode.decode!( 200 | input, 201 | Perftools.Profiles.Function, 202 | &json_library_wrapper.decode!(json_library, &1) 203 | ) 204 | end 205 | 206 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 207 | def json_encode(msg, opts \\ []) do 208 | try do 209 | {:ok, json_encode!(msg, opts)} 210 | rescue 211 | e in Protox.JsonEncodingError -> {:error, e} 212 | end 213 | end 214 | 215 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 216 | def json_encode!(msg, opts \\ []) do 217 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 218 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 219 | end 220 | ) 221 | 222 | ( 223 | @deprecated "Use fields_defs()/0 instead" 224 | @spec defs() :: %{ 225 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 226 | } 227 | def defs() do 228 | %{ 229 | 1 => {:id, {:scalar, 0}, :uint64}, 230 | 2 => {:name, {:scalar, 0}, :int64}, 231 | 3 => {:system_name, {:scalar, 0}, :int64}, 232 | 4 => {:filename, {:scalar, 0}, :int64}, 233 | 5 => {:start_line, {:scalar, 0}, :int64} 234 | } 235 | end 236 | 237 | @deprecated "Use fields_defs()/0 instead" 238 | @spec defs_by_name() :: %{ 239 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 240 | } 241 | def defs_by_name() do 242 | %{ 243 | filename: {4, {:scalar, 0}, :int64}, 244 | id: {1, {:scalar, 0}, :uint64}, 245 | name: {2, {:scalar, 0}, :int64}, 246 | start_line: {5, {:scalar, 0}, :int64}, 247 | system_name: {3, {:scalar, 0}, :int64} 248 | } 249 | end 250 | ) 251 | 252 | ( 253 | @spec fields_defs() :: list(Protox.Field.t()) 254 | def fields_defs() do 255 | [ 256 | %{ 257 | __struct__: Protox.Field, 258 | json_name: "id", 259 | kind: {:scalar, 0}, 260 | label: :optional, 261 | name: :id, 262 | tag: 1, 263 | type: :uint64 264 | }, 265 | %{ 266 | __struct__: Protox.Field, 267 | json_name: "name", 268 | kind: {:scalar, 0}, 269 | label: :optional, 270 | name: :name, 271 | tag: 2, 272 | type: :int64 273 | }, 274 | %{ 275 | __struct__: Protox.Field, 276 | json_name: "systemName", 277 | kind: {:scalar, 0}, 278 | label: :optional, 279 | name: :system_name, 280 | tag: 3, 281 | type: :int64 282 | }, 283 | %{ 284 | __struct__: Protox.Field, 285 | json_name: "filename", 286 | kind: {:scalar, 0}, 287 | label: :optional, 288 | name: :filename, 289 | tag: 4, 290 | type: :int64 291 | }, 292 | %{ 293 | __struct__: Protox.Field, 294 | json_name: "startLine", 295 | kind: {:scalar, 0}, 296 | label: :optional, 297 | name: :start_line, 298 | tag: 5, 299 | type: :int64 300 | } 301 | ] 302 | end 303 | 304 | [ 305 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 306 | ( 307 | def field_def(:id) do 308 | {:ok, 309 | %{ 310 | __struct__: Protox.Field, 311 | json_name: "id", 312 | kind: {:scalar, 0}, 313 | label: :optional, 314 | name: :id, 315 | tag: 1, 316 | type: :uint64 317 | }} 318 | end 319 | 320 | def field_def("id") do 321 | {:ok, 322 | %{ 323 | __struct__: Protox.Field, 324 | json_name: "id", 325 | kind: {:scalar, 0}, 326 | label: :optional, 327 | name: :id, 328 | tag: 1, 329 | type: :uint64 330 | }} 331 | end 332 | 333 | [] 334 | ), 335 | ( 336 | def field_def(:name) do 337 | {:ok, 338 | %{ 339 | __struct__: Protox.Field, 340 | json_name: "name", 341 | kind: {:scalar, 0}, 342 | label: :optional, 343 | name: :name, 344 | tag: 2, 345 | type: :int64 346 | }} 347 | end 348 | 349 | def field_def("name") do 350 | {:ok, 351 | %{ 352 | __struct__: Protox.Field, 353 | json_name: "name", 354 | kind: {:scalar, 0}, 355 | label: :optional, 356 | name: :name, 357 | tag: 2, 358 | type: :int64 359 | }} 360 | end 361 | 362 | [] 363 | ), 364 | ( 365 | def field_def(:system_name) do 366 | {:ok, 367 | %{ 368 | __struct__: Protox.Field, 369 | json_name: "systemName", 370 | kind: {:scalar, 0}, 371 | label: :optional, 372 | name: :system_name, 373 | tag: 3, 374 | type: :int64 375 | }} 376 | end 377 | 378 | def field_def("systemName") do 379 | {:ok, 380 | %{ 381 | __struct__: Protox.Field, 382 | json_name: "systemName", 383 | kind: {:scalar, 0}, 384 | label: :optional, 385 | name: :system_name, 386 | tag: 3, 387 | type: :int64 388 | }} 389 | end 390 | 391 | def field_def("system_name") do 392 | {:ok, 393 | %{ 394 | __struct__: Protox.Field, 395 | json_name: "systemName", 396 | kind: {:scalar, 0}, 397 | label: :optional, 398 | name: :system_name, 399 | tag: 3, 400 | type: :int64 401 | }} 402 | end 403 | ), 404 | ( 405 | def field_def(:filename) do 406 | {:ok, 407 | %{ 408 | __struct__: Protox.Field, 409 | json_name: "filename", 410 | kind: {:scalar, 0}, 411 | label: :optional, 412 | name: :filename, 413 | tag: 4, 414 | type: :int64 415 | }} 416 | end 417 | 418 | def field_def("filename") do 419 | {:ok, 420 | %{ 421 | __struct__: Protox.Field, 422 | json_name: "filename", 423 | kind: {:scalar, 0}, 424 | label: :optional, 425 | name: :filename, 426 | tag: 4, 427 | type: :int64 428 | }} 429 | end 430 | 431 | [] 432 | ), 433 | ( 434 | def field_def(:start_line) do 435 | {:ok, 436 | %{ 437 | __struct__: Protox.Field, 438 | json_name: "startLine", 439 | kind: {:scalar, 0}, 440 | label: :optional, 441 | name: :start_line, 442 | tag: 5, 443 | type: :int64 444 | }} 445 | end 446 | 447 | def field_def("startLine") do 448 | {:ok, 449 | %{ 450 | __struct__: Protox.Field, 451 | json_name: "startLine", 452 | kind: {:scalar, 0}, 453 | label: :optional, 454 | name: :start_line, 455 | tag: 5, 456 | type: :int64 457 | }} 458 | end 459 | 460 | def field_def("start_line") do 461 | {:ok, 462 | %{ 463 | __struct__: Protox.Field, 464 | json_name: "startLine", 465 | kind: {:scalar, 0}, 466 | label: :optional, 467 | name: :start_line, 468 | tag: 5, 469 | type: :int64 470 | }} 471 | end 472 | ), 473 | def field_def(_) do 474 | {:error, :no_such_field} 475 | end 476 | ] 477 | ) 478 | 479 | ( 480 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 481 | def unknown_fields(msg) do 482 | msg.__uf__ 483 | end 484 | 485 | @spec unknown_fields_name() :: :__uf__ 486 | def unknown_fields_name() do 487 | :__uf__ 488 | end 489 | 490 | @spec clear_unknown_fields(struct) :: struct 491 | def clear_unknown_fields(msg) do 492 | struct!(msg, [{unknown_fields_name(), []}]) 493 | end 494 | ) 495 | 496 | ( 497 | @spec required_fields() :: [] 498 | def required_fields() do 499 | [] 500 | end 501 | ) 502 | 503 | ( 504 | @spec syntax() :: atom() 505 | def syntax() do 506 | :proto3 507 | end 508 | ) 509 | 510 | [ 511 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 512 | def default(:id) do 513 | {:ok, 0} 514 | end, 515 | def default(:name) do 516 | {:ok, 0} 517 | end, 518 | def default(:system_name) do 519 | {:ok, 0} 520 | end, 521 | def default(:filename) do 522 | {:ok, 0} 523 | end, 524 | def default(:start_line) do 525 | {:ok, 0} 526 | end, 527 | def default(_) do 528 | {:error, :no_such_field} 529 | end 530 | ] 531 | 532 | ( 533 | @spec file_options() :: struct() 534 | def file_options() do 535 | file_options = %{ 536 | __struct__: Protox.Google.Protobuf.FileOptions, 537 | __uf__: [], 538 | cc_enable_arenas: nil, 539 | cc_generic_services: nil, 540 | csharp_namespace: nil, 541 | deprecated: nil, 542 | go_package: nil, 543 | java_generate_equals_and_hash: nil, 544 | java_generic_services: nil, 545 | java_multiple_files: nil, 546 | java_outer_classname: "ProfileProto", 547 | java_package: "com.google.perftools.profiles", 548 | java_string_check_utf8: nil, 549 | objc_class_prefix: nil, 550 | optimize_for: nil, 551 | php_class_prefix: nil, 552 | php_generic_services: nil, 553 | php_metadata_namespace: nil, 554 | php_namespace: nil, 555 | py_generic_services: nil, 556 | ruby_package: nil, 557 | swift_prefix: nil, 558 | uninterpreted_option: [] 559 | } 560 | 561 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 562 | true -> 563 | bytes = 564 | file_options 565 | |> Protox.Google.Protobuf.FileOptions.encode!() 566 | |> :binary.list_to_bin() 567 | 568 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 569 | 570 | false -> 571 | file_options 572 | end 573 | end 574 | ) 575 | end, 576 | defmodule Perftools.Profiles.Label do 577 | @moduledoc false 578 | defstruct key: 0, str: 0, num: 0, num_unit: 0, __uf__: [] 579 | 580 | ( 581 | ( 582 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 583 | def encode(msg) do 584 | try do 585 | {:ok, encode!(msg)} 586 | rescue 587 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 588 | end 589 | end 590 | 591 | @spec encode!(struct) :: iodata | no_return 592 | def encode!(msg) do 593 | [] 594 | |> encode_key(msg) 595 | |> encode_str(msg) 596 | |> encode_num(msg) 597 | |> encode_num_unit(msg) 598 | |> encode_unknown_fields(msg) 599 | end 600 | ) 601 | 602 | [] 603 | 604 | [ 605 | defp encode_key(acc, msg) do 606 | try do 607 | if msg.key == 0 do 608 | acc 609 | else 610 | [acc, "\b", Protox.Encode.encode_int64(msg.key)] 611 | end 612 | rescue 613 | ArgumentError -> 614 | reraise Protox.EncodingError.new(:key, "invalid field value"), __STACKTRACE__ 615 | end 616 | end, 617 | defp encode_str(acc, msg) do 618 | try do 619 | if msg.str == 0 do 620 | acc 621 | else 622 | [acc, "\x10", Protox.Encode.encode_int64(msg.str)] 623 | end 624 | rescue 625 | ArgumentError -> 626 | reraise Protox.EncodingError.new(:str, "invalid field value"), __STACKTRACE__ 627 | end 628 | end, 629 | defp encode_num(acc, msg) do 630 | try do 631 | if msg.num == 0 do 632 | acc 633 | else 634 | [acc, "\x18", Protox.Encode.encode_int64(msg.num)] 635 | end 636 | rescue 637 | ArgumentError -> 638 | reraise Protox.EncodingError.new(:num, "invalid field value"), __STACKTRACE__ 639 | end 640 | end, 641 | defp encode_num_unit(acc, msg) do 642 | try do 643 | if msg.num_unit == 0 do 644 | acc 645 | else 646 | [acc, " ", Protox.Encode.encode_int64(msg.num_unit)] 647 | end 648 | rescue 649 | ArgumentError -> 650 | reraise Protox.EncodingError.new(:num_unit, "invalid field value"), __STACKTRACE__ 651 | end 652 | end 653 | ] 654 | 655 | defp encode_unknown_fields(acc, msg) do 656 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 657 | case wire_type do 658 | 0 -> 659 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 660 | 661 | 1 -> 662 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 663 | 664 | 2 -> 665 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 666 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 667 | 668 | 5 -> 669 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 670 | end 671 | end) 672 | end 673 | ) 674 | 675 | ( 676 | ( 677 | @spec decode(binary) :: {:ok, struct} | {:error, any} 678 | def decode(bytes) do 679 | try do 680 | {:ok, decode!(bytes)} 681 | rescue 682 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 683 | {:error, e} 684 | end 685 | end 686 | 687 | ( 688 | @spec decode!(binary) :: struct | no_return 689 | def decode!(bytes) do 690 | parse_key_value(bytes, struct(Perftools.Profiles.Label)) 691 | end 692 | ) 693 | ) 694 | 695 | ( 696 | @spec parse_key_value(binary, struct) :: struct 697 | defp parse_key_value(<<>>, msg) do 698 | msg 699 | end 700 | 701 | defp parse_key_value(bytes, msg) do 702 | {field, rest} = 703 | case Protox.Decode.parse_key(bytes) do 704 | {0, _, _} -> 705 | raise %Protox.IllegalTagError{} 706 | 707 | {1, _, bytes} -> 708 | {value, rest} = Protox.Decode.parse_int64(bytes) 709 | {[key: value], rest} 710 | 711 | {2, _, bytes} -> 712 | {value, rest} = Protox.Decode.parse_int64(bytes) 713 | {[str: value], rest} 714 | 715 | {3, _, bytes} -> 716 | {value, rest} = Protox.Decode.parse_int64(bytes) 717 | {[num: value], rest} 718 | 719 | {4, _, bytes} -> 720 | {value, rest} = Protox.Decode.parse_int64(bytes) 721 | {[num_unit: value], rest} 722 | 723 | {tag, wire_type, rest} -> 724 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 725 | 726 | {[ 727 | {msg.__struct__.unknown_fields_name, 728 | [value | msg.__struct__.unknown_fields(msg)]} 729 | ], rest} 730 | end 731 | 732 | msg_updated = struct(msg, field) 733 | parse_key_value(rest, msg_updated) 734 | end 735 | ) 736 | 737 | [] 738 | ) 739 | 740 | ( 741 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 742 | def json_decode(input, opts \\ []) do 743 | try do 744 | {:ok, json_decode!(input, opts)} 745 | rescue 746 | e in Protox.JsonDecodingError -> {:error, e} 747 | end 748 | end 749 | 750 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 751 | def json_decode!(input, opts \\ []) do 752 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 753 | 754 | Protox.JsonDecode.decode!( 755 | input, 756 | Perftools.Profiles.Label, 757 | &json_library_wrapper.decode!(json_library, &1) 758 | ) 759 | end 760 | 761 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 762 | def json_encode(msg, opts \\ []) do 763 | try do 764 | {:ok, json_encode!(msg, opts)} 765 | rescue 766 | e in Protox.JsonEncodingError -> {:error, e} 767 | end 768 | end 769 | 770 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 771 | def json_encode!(msg, opts \\ []) do 772 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 773 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 774 | end 775 | ) 776 | 777 | ( 778 | @deprecated "Use fields_defs()/0 instead" 779 | @spec defs() :: %{ 780 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 781 | } 782 | def defs() do 783 | %{ 784 | 1 => {:key, {:scalar, 0}, :int64}, 785 | 2 => {:str, {:scalar, 0}, :int64}, 786 | 3 => {:num, {:scalar, 0}, :int64}, 787 | 4 => {:num_unit, {:scalar, 0}, :int64} 788 | } 789 | end 790 | 791 | @deprecated "Use fields_defs()/0 instead" 792 | @spec defs_by_name() :: %{ 793 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 794 | } 795 | def defs_by_name() do 796 | %{ 797 | key: {1, {:scalar, 0}, :int64}, 798 | num: {3, {:scalar, 0}, :int64}, 799 | num_unit: {4, {:scalar, 0}, :int64}, 800 | str: {2, {:scalar, 0}, :int64} 801 | } 802 | end 803 | ) 804 | 805 | ( 806 | @spec fields_defs() :: list(Protox.Field.t()) 807 | def fields_defs() do 808 | [ 809 | %{ 810 | __struct__: Protox.Field, 811 | json_name: "key", 812 | kind: {:scalar, 0}, 813 | label: :optional, 814 | name: :key, 815 | tag: 1, 816 | type: :int64 817 | }, 818 | %{ 819 | __struct__: Protox.Field, 820 | json_name: "str", 821 | kind: {:scalar, 0}, 822 | label: :optional, 823 | name: :str, 824 | tag: 2, 825 | type: :int64 826 | }, 827 | %{ 828 | __struct__: Protox.Field, 829 | json_name: "num", 830 | kind: {:scalar, 0}, 831 | label: :optional, 832 | name: :num, 833 | tag: 3, 834 | type: :int64 835 | }, 836 | %{ 837 | __struct__: Protox.Field, 838 | json_name: "numUnit", 839 | kind: {:scalar, 0}, 840 | label: :optional, 841 | name: :num_unit, 842 | tag: 4, 843 | type: :int64 844 | } 845 | ] 846 | end 847 | 848 | [ 849 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 850 | ( 851 | def field_def(:key) do 852 | {:ok, 853 | %{ 854 | __struct__: Protox.Field, 855 | json_name: "key", 856 | kind: {:scalar, 0}, 857 | label: :optional, 858 | name: :key, 859 | tag: 1, 860 | type: :int64 861 | }} 862 | end 863 | 864 | def field_def("key") do 865 | {:ok, 866 | %{ 867 | __struct__: Protox.Field, 868 | json_name: "key", 869 | kind: {:scalar, 0}, 870 | label: :optional, 871 | name: :key, 872 | tag: 1, 873 | type: :int64 874 | }} 875 | end 876 | 877 | [] 878 | ), 879 | ( 880 | def field_def(:str) do 881 | {:ok, 882 | %{ 883 | __struct__: Protox.Field, 884 | json_name: "str", 885 | kind: {:scalar, 0}, 886 | label: :optional, 887 | name: :str, 888 | tag: 2, 889 | type: :int64 890 | }} 891 | end 892 | 893 | def field_def("str") do 894 | {:ok, 895 | %{ 896 | __struct__: Protox.Field, 897 | json_name: "str", 898 | kind: {:scalar, 0}, 899 | label: :optional, 900 | name: :str, 901 | tag: 2, 902 | type: :int64 903 | }} 904 | end 905 | 906 | [] 907 | ), 908 | ( 909 | def field_def(:num) do 910 | {:ok, 911 | %{ 912 | __struct__: Protox.Field, 913 | json_name: "num", 914 | kind: {:scalar, 0}, 915 | label: :optional, 916 | name: :num, 917 | tag: 3, 918 | type: :int64 919 | }} 920 | end 921 | 922 | def field_def("num") do 923 | {:ok, 924 | %{ 925 | __struct__: Protox.Field, 926 | json_name: "num", 927 | kind: {:scalar, 0}, 928 | label: :optional, 929 | name: :num, 930 | tag: 3, 931 | type: :int64 932 | }} 933 | end 934 | 935 | [] 936 | ), 937 | ( 938 | def field_def(:num_unit) do 939 | {:ok, 940 | %{ 941 | __struct__: Protox.Field, 942 | json_name: "numUnit", 943 | kind: {:scalar, 0}, 944 | label: :optional, 945 | name: :num_unit, 946 | tag: 4, 947 | type: :int64 948 | }} 949 | end 950 | 951 | def field_def("numUnit") do 952 | {:ok, 953 | %{ 954 | __struct__: Protox.Field, 955 | json_name: "numUnit", 956 | kind: {:scalar, 0}, 957 | label: :optional, 958 | name: :num_unit, 959 | tag: 4, 960 | type: :int64 961 | }} 962 | end 963 | 964 | def field_def("num_unit") do 965 | {:ok, 966 | %{ 967 | __struct__: Protox.Field, 968 | json_name: "numUnit", 969 | kind: {:scalar, 0}, 970 | label: :optional, 971 | name: :num_unit, 972 | tag: 4, 973 | type: :int64 974 | }} 975 | end 976 | ), 977 | def field_def(_) do 978 | {:error, :no_such_field} 979 | end 980 | ] 981 | ) 982 | 983 | ( 984 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 985 | def unknown_fields(msg) do 986 | msg.__uf__ 987 | end 988 | 989 | @spec unknown_fields_name() :: :__uf__ 990 | def unknown_fields_name() do 991 | :__uf__ 992 | end 993 | 994 | @spec clear_unknown_fields(struct) :: struct 995 | def clear_unknown_fields(msg) do 996 | struct!(msg, [{unknown_fields_name(), []}]) 997 | end 998 | ) 999 | 1000 | ( 1001 | @spec required_fields() :: [] 1002 | def required_fields() do 1003 | [] 1004 | end 1005 | ) 1006 | 1007 | ( 1008 | @spec syntax() :: atom() 1009 | def syntax() do 1010 | :proto3 1011 | end 1012 | ) 1013 | 1014 | [ 1015 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 1016 | def default(:key) do 1017 | {:ok, 0} 1018 | end, 1019 | def default(:str) do 1020 | {:ok, 0} 1021 | end, 1022 | def default(:num) do 1023 | {:ok, 0} 1024 | end, 1025 | def default(:num_unit) do 1026 | {:ok, 0} 1027 | end, 1028 | def default(_) do 1029 | {:error, :no_such_field} 1030 | end 1031 | ] 1032 | 1033 | ( 1034 | @spec file_options() :: struct() 1035 | def file_options() do 1036 | file_options = %{ 1037 | __struct__: Protox.Google.Protobuf.FileOptions, 1038 | __uf__: [], 1039 | cc_enable_arenas: nil, 1040 | cc_generic_services: nil, 1041 | csharp_namespace: nil, 1042 | deprecated: nil, 1043 | go_package: nil, 1044 | java_generate_equals_and_hash: nil, 1045 | java_generic_services: nil, 1046 | java_multiple_files: nil, 1047 | java_outer_classname: "ProfileProto", 1048 | java_package: "com.google.perftools.profiles", 1049 | java_string_check_utf8: nil, 1050 | objc_class_prefix: nil, 1051 | optimize_for: nil, 1052 | php_class_prefix: nil, 1053 | php_generic_services: nil, 1054 | php_metadata_namespace: nil, 1055 | php_namespace: nil, 1056 | py_generic_services: nil, 1057 | ruby_package: nil, 1058 | swift_prefix: nil, 1059 | uninterpreted_option: [] 1060 | } 1061 | 1062 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 1063 | true -> 1064 | bytes = 1065 | file_options 1066 | |> Protox.Google.Protobuf.FileOptions.encode!() 1067 | |> :binary.list_to_bin() 1068 | 1069 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 1070 | 1071 | false -> 1072 | file_options 1073 | end 1074 | end 1075 | ) 1076 | end, 1077 | defmodule Perftools.Profiles.Line do 1078 | @moduledoc false 1079 | defstruct function_id: 0, line: 0, __uf__: [] 1080 | 1081 | ( 1082 | ( 1083 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 1084 | def encode(msg) do 1085 | try do 1086 | {:ok, encode!(msg)} 1087 | rescue 1088 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 1089 | end 1090 | end 1091 | 1092 | @spec encode!(struct) :: iodata | no_return 1093 | def encode!(msg) do 1094 | [] |> encode_function_id(msg) |> encode_line(msg) |> encode_unknown_fields(msg) 1095 | end 1096 | ) 1097 | 1098 | [] 1099 | 1100 | [ 1101 | defp encode_function_id(acc, msg) do 1102 | try do 1103 | if msg.function_id == 0 do 1104 | acc 1105 | else 1106 | [acc, "\b", Protox.Encode.encode_uint64(msg.function_id)] 1107 | end 1108 | rescue 1109 | ArgumentError -> 1110 | reraise Protox.EncodingError.new(:function_id, "invalid field value"), 1111 | __STACKTRACE__ 1112 | end 1113 | end, 1114 | defp encode_line(acc, msg) do 1115 | try do 1116 | if msg.line == 0 do 1117 | acc 1118 | else 1119 | [acc, "\x10", Protox.Encode.encode_int64(msg.line)] 1120 | end 1121 | rescue 1122 | ArgumentError -> 1123 | reraise Protox.EncodingError.new(:line, "invalid field value"), __STACKTRACE__ 1124 | end 1125 | end 1126 | ] 1127 | 1128 | defp encode_unknown_fields(acc, msg) do 1129 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 1130 | case wire_type do 1131 | 0 -> 1132 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 1133 | 1134 | 1 -> 1135 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 1136 | 1137 | 2 -> 1138 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 1139 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 1140 | 1141 | 5 -> 1142 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 1143 | end 1144 | end) 1145 | end 1146 | ) 1147 | 1148 | ( 1149 | ( 1150 | @spec decode(binary) :: {:ok, struct} | {:error, any} 1151 | def decode(bytes) do 1152 | try do 1153 | {:ok, decode!(bytes)} 1154 | rescue 1155 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 1156 | {:error, e} 1157 | end 1158 | end 1159 | 1160 | ( 1161 | @spec decode!(binary) :: struct | no_return 1162 | def decode!(bytes) do 1163 | parse_key_value(bytes, struct(Perftools.Profiles.Line)) 1164 | end 1165 | ) 1166 | ) 1167 | 1168 | ( 1169 | @spec parse_key_value(binary, struct) :: struct 1170 | defp parse_key_value(<<>>, msg) do 1171 | msg 1172 | end 1173 | 1174 | defp parse_key_value(bytes, msg) do 1175 | {field, rest} = 1176 | case Protox.Decode.parse_key(bytes) do 1177 | {0, _, _} -> 1178 | raise %Protox.IllegalTagError{} 1179 | 1180 | {1, _, bytes} -> 1181 | {value, rest} = Protox.Decode.parse_uint64(bytes) 1182 | {[function_id: value], rest} 1183 | 1184 | {2, _, bytes} -> 1185 | {value, rest} = Protox.Decode.parse_int64(bytes) 1186 | {[line: value], rest} 1187 | 1188 | {tag, wire_type, rest} -> 1189 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 1190 | 1191 | {[ 1192 | {msg.__struct__.unknown_fields_name, 1193 | [value | msg.__struct__.unknown_fields(msg)]} 1194 | ], rest} 1195 | end 1196 | 1197 | msg_updated = struct(msg, field) 1198 | parse_key_value(rest, msg_updated) 1199 | end 1200 | ) 1201 | 1202 | [] 1203 | ) 1204 | 1205 | ( 1206 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 1207 | def json_decode(input, opts \\ []) do 1208 | try do 1209 | {:ok, json_decode!(input, opts)} 1210 | rescue 1211 | e in Protox.JsonDecodingError -> {:error, e} 1212 | end 1213 | end 1214 | 1215 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 1216 | def json_decode!(input, opts \\ []) do 1217 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 1218 | 1219 | Protox.JsonDecode.decode!( 1220 | input, 1221 | Perftools.Profiles.Line, 1222 | &json_library_wrapper.decode!(json_library, &1) 1223 | ) 1224 | end 1225 | 1226 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 1227 | def json_encode(msg, opts \\ []) do 1228 | try do 1229 | {:ok, json_encode!(msg, opts)} 1230 | rescue 1231 | e in Protox.JsonEncodingError -> {:error, e} 1232 | end 1233 | end 1234 | 1235 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 1236 | def json_encode!(msg, opts \\ []) do 1237 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 1238 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 1239 | end 1240 | ) 1241 | 1242 | ( 1243 | @deprecated "Use fields_defs()/0 instead" 1244 | @spec defs() :: %{ 1245 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 1246 | } 1247 | def defs() do 1248 | %{1 => {:function_id, {:scalar, 0}, :uint64}, 2 => {:line, {:scalar, 0}, :int64}} 1249 | end 1250 | 1251 | @deprecated "Use fields_defs()/0 instead" 1252 | @spec defs_by_name() :: %{ 1253 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 1254 | } 1255 | def defs_by_name() do 1256 | %{function_id: {1, {:scalar, 0}, :uint64}, line: {2, {:scalar, 0}, :int64}} 1257 | end 1258 | ) 1259 | 1260 | ( 1261 | @spec fields_defs() :: list(Protox.Field.t()) 1262 | def fields_defs() do 1263 | [ 1264 | %{ 1265 | __struct__: Protox.Field, 1266 | json_name: "functionId", 1267 | kind: {:scalar, 0}, 1268 | label: :optional, 1269 | name: :function_id, 1270 | tag: 1, 1271 | type: :uint64 1272 | }, 1273 | %{ 1274 | __struct__: Protox.Field, 1275 | json_name: "line", 1276 | kind: {:scalar, 0}, 1277 | label: :optional, 1278 | name: :line, 1279 | tag: 2, 1280 | type: :int64 1281 | } 1282 | ] 1283 | end 1284 | 1285 | [ 1286 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 1287 | ( 1288 | def field_def(:function_id) do 1289 | {:ok, 1290 | %{ 1291 | __struct__: Protox.Field, 1292 | json_name: "functionId", 1293 | kind: {:scalar, 0}, 1294 | label: :optional, 1295 | name: :function_id, 1296 | tag: 1, 1297 | type: :uint64 1298 | }} 1299 | end 1300 | 1301 | def field_def("functionId") do 1302 | {:ok, 1303 | %{ 1304 | __struct__: Protox.Field, 1305 | json_name: "functionId", 1306 | kind: {:scalar, 0}, 1307 | label: :optional, 1308 | name: :function_id, 1309 | tag: 1, 1310 | type: :uint64 1311 | }} 1312 | end 1313 | 1314 | def field_def("function_id") do 1315 | {:ok, 1316 | %{ 1317 | __struct__: Protox.Field, 1318 | json_name: "functionId", 1319 | kind: {:scalar, 0}, 1320 | label: :optional, 1321 | name: :function_id, 1322 | tag: 1, 1323 | type: :uint64 1324 | }} 1325 | end 1326 | ), 1327 | ( 1328 | def field_def(:line) do 1329 | {:ok, 1330 | %{ 1331 | __struct__: Protox.Field, 1332 | json_name: "line", 1333 | kind: {:scalar, 0}, 1334 | label: :optional, 1335 | name: :line, 1336 | tag: 2, 1337 | type: :int64 1338 | }} 1339 | end 1340 | 1341 | def field_def("line") do 1342 | {:ok, 1343 | %{ 1344 | __struct__: Protox.Field, 1345 | json_name: "line", 1346 | kind: {:scalar, 0}, 1347 | label: :optional, 1348 | name: :line, 1349 | tag: 2, 1350 | type: :int64 1351 | }} 1352 | end 1353 | 1354 | [] 1355 | ), 1356 | def field_def(_) do 1357 | {:error, :no_such_field} 1358 | end 1359 | ] 1360 | ) 1361 | 1362 | ( 1363 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 1364 | def unknown_fields(msg) do 1365 | msg.__uf__ 1366 | end 1367 | 1368 | @spec unknown_fields_name() :: :__uf__ 1369 | def unknown_fields_name() do 1370 | :__uf__ 1371 | end 1372 | 1373 | @spec clear_unknown_fields(struct) :: struct 1374 | def clear_unknown_fields(msg) do 1375 | struct!(msg, [{unknown_fields_name(), []}]) 1376 | end 1377 | ) 1378 | 1379 | ( 1380 | @spec required_fields() :: [] 1381 | def required_fields() do 1382 | [] 1383 | end 1384 | ) 1385 | 1386 | ( 1387 | @spec syntax() :: atom() 1388 | def syntax() do 1389 | :proto3 1390 | end 1391 | ) 1392 | 1393 | [ 1394 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 1395 | def default(:function_id) do 1396 | {:ok, 0} 1397 | end, 1398 | def default(:line) do 1399 | {:ok, 0} 1400 | end, 1401 | def default(_) do 1402 | {:error, :no_such_field} 1403 | end 1404 | ] 1405 | 1406 | ( 1407 | @spec file_options() :: struct() 1408 | def file_options() do 1409 | file_options = %{ 1410 | __struct__: Protox.Google.Protobuf.FileOptions, 1411 | __uf__: [], 1412 | cc_enable_arenas: nil, 1413 | cc_generic_services: nil, 1414 | csharp_namespace: nil, 1415 | deprecated: nil, 1416 | go_package: nil, 1417 | java_generate_equals_and_hash: nil, 1418 | java_generic_services: nil, 1419 | java_multiple_files: nil, 1420 | java_outer_classname: "ProfileProto", 1421 | java_package: "com.google.perftools.profiles", 1422 | java_string_check_utf8: nil, 1423 | objc_class_prefix: nil, 1424 | optimize_for: nil, 1425 | php_class_prefix: nil, 1426 | php_generic_services: nil, 1427 | php_metadata_namespace: nil, 1428 | php_namespace: nil, 1429 | py_generic_services: nil, 1430 | ruby_package: nil, 1431 | swift_prefix: nil, 1432 | uninterpreted_option: [] 1433 | } 1434 | 1435 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 1436 | true -> 1437 | bytes = 1438 | file_options 1439 | |> Protox.Google.Protobuf.FileOptions.encode!() 1440 | |> :binary.list_to_bin() 1441 | 1442 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 1443 | 1444 | false -> 1445 | file_options 1446 | end 1447 | end 1448 | ) 1449 | end, 1450 | defmodule Perftools.Profiles.Location do 1451 | @moduledoc false 1452 | defstruct id: 0, mapping_id: 0, address: 0, line: [], is_folded: false, __uf__: [] 1453 | 1454 | ( 1455 | ( 1456 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 1457 | def encode(msg) do 1458 | try do 1459 | {:ok, encode!(msg)} 1460 | rescue 1461 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 1462 | end 1463 | end 1464 | 1465 | @spec encode!(struct) :: iodata | no_return 1466 | def encode!(msg) do 1467 | [] 1468 | |> encode_id(msg) 1469 | |> encode_mapping_id(msg) 1470 | |> encode_address(msg) 1471 | |> encode_line(msg) 1472 | |> encode_is_folded(msg) 1473 | |> encode_unknown_fields(msg) 1474 | end 1475 | ) 1476 | 1477 | [] 1478 | 1479 | [ 1480 | defp encode_id(acc, msg) do 1481 | try do 1482 | if msg.id == 0 do 1483 | acc 1484 | else 1485 | [acc, "\b", Protox.Encode.encode_uint64(msg.id)] 1486 | end 1487 | rescue 1488 | ArgumentError -> 1489 | reraise Protox.EncodingError.new(:id, "invalid field value"), __STACKTRACE__ 1490 | end 1491 | end, 1492 | defp encode_mapping_id(acc, msg) do 1493 | try do 1494 | if msg.mapping_id == 0 do 1495 | acc 1496 | else 1497 | [acc, "\x10", Protox.Encode.encode_uint64(msg.mapping_id)] 1498 | end 1499 | rescue 1500 | ArgumentError -> 1501 | reraise Protox.EncodingError.new(:mapping_id, "invalid field value"), __STACKTRACE__ 1502 | end 1503 | end, 1504 | defp encode_address(acc, msg) do 1505 | try do 1506 | if msg.address == 0 do 1507 | acc 1508 | else 1509 | [acc, "\x18", Protox.Encode.encode_uint64(msg.address)] 1510 | end 1511 | rescue 1512 | ArgumentError -> 1513 | reraise Protox.EncodingError.new(:address, "invalid field value"), __STACKTRACE__ 1514 | end 1515 | end, 1516 | defp encode_line(acc, msg) do 1517 | try do 1518 | case msg.line do 1519 | [] -> 1520 | acc 1521 | 1522 | values -> 1523 | [ 1524 | acc, 1525 | Enum.reduce(values, [], fn value, acc -> 1526 | [acc, "\"", Protox.Encode.encode_message(value)] 1527 | end) 1528 | ] 1529 | end 1530 | rescue 1531 | ArgumentError -> 1532 | reraise Protox.EncodingError.new(:line, "invalid field value"), __STACKTRACE__ 1533 | end 1534 | end, 1535 | defp encode_is_folded(acc, msg) do 1536 | try do 1537 | if msg.is_folded == false do 1538 | acc 1539 | else 1540 | [acc, "(", Protox.Encode.encode_bool(msg.is_folded)] 1541 | end 1542 | rescue 1543 | ArgumentError -> 1544 | reraise Protox.EncodingError.new(:is_folded, "invalid field value"), __STACKTRACE__ 1545 | end 1546 | end 1547 | ] 1548 | 1549 | defp encode_unknown_fields(acc, msg) do 1550 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 1551 | case wire_type do 1552 | 0 -> 1553 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 1554 | 1555 | 1 -> 1556 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 1557 | 1558 | 2 -> 1559 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 1560 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 1561 | 1562 | 5 -> 1563 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 1564 | end 1565 | end) 1566 | end 1567 | ) 1568 | 1569 | ( 1570 | ( 1571 | @spec decode(binary) :: {:ok, struct} | {:error, any} 1572 | def decode(bytes) do 1573 | try do 1574 | {:ok, decode!(bytes)} 1575 | rescue 1576 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 1577 | {:error, e} 1578 | end 1579 | end 1580 | 1581 | ( 1582 | @spec decode!(binary) :: struct | no_return 1583 | def decode!(bytes) do 1584 | parse_key_value(bytes, struct(Perftools.Profiles.Location)) 1585 | end 1586 | ) 1587 | ) 1588 | 1589 | ( 1590 | @spec parse_key_value(binary, struct) :: struct 1591 | defp parse_key_value(<<>>, msg) do 1592 | msg 1593 | end 1594 | 1595 | defp parse_key_value(bytes, msg) do 1596 | {field, rest} = 1597 | case Protox.Decode.parse_key(bytes) do 1598 | {0, _, _} -> 1599 | raise %Protox.IllegalTagError{} 1600 | 1601 | {1, _, bytes} -> 1602 | {value, rest} = Protox.Decode.parse_uint64(bytes) 1603 | {[id: value], rest} 1604 | 1605 | {2, _, bytes} -> 1606 | {value, rest} = Protox.Decode.parse_uint64(bytes) 1607 | {[mapping_id: value], rest} 1608 | 1609 | {3, _, bytes} -> 1610 | {value, rest} = Protox.Decode.parse_uint64(bytes) 1611 | {[address: value], rest} 1612 | 1613 | {4, _, bytes} -> 1614 | {len, bytes} = Protox.Varint.decode(bytes) 1615 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 1616 | {[line: msg.line ++ [Perftools.Profiles.Line.decode!(delimited)]], rest} 1617 | 1618 | {5, _, bytes} -> 1619 | {value, rest} = Protox.Decode.parse_bool(bytes) 1620 | {[is_folded: value], rest} 1621 | 1622 | {tag, wire_type, rest} -> 1623 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 1624 | 1625 | {[ 1626 | {msg.__struct__.unknown_fields_name, 1627 | [value | msg.__struct__.unknown_fields(msg)]} 1628 | ], rest} 1629 | end 1630 | 1631 | msg_updated = struct(msg, field) 1632 | parse_key_value(rest, msg_updated) 1633 | end 1634 | ) 1635 | 1636 | [] 1637 | ) 1638 | 1639 | ( 1640 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 1641 | def json_decode(input, opts \\ []) do 1642 | try do 1643 | {:ok, json_decode!(input, opts)} 1644 | rescue 1645 | e in Protox.JsonDecodingError -> {:error, e} 1646 | end 1647 | end 1648 | 1649 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 1650 | def json_decode!(input, opts \\ []) do 1651 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 1652 | 1653 | Protox.JsonDecode.decode!( 1654 | input, 1655 | Perftools.Profiles.Location, 1656 | &json_library_wrapper.decode!(json_library, &1) 1657 | ) 1658 | end 1659 | 1660 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 1661 | def json_encode(msg, opts \\ []) do 1662 | try do 1663 | {:ok, json_encode!(msg, opts)} 1664 | rescue 1665 | e in Protox.JsonEncodingError -> {:error, e} 1666 | end 1667 | end 1668 | 1669 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 1670 | def json_encode!(msg, opts \\ []) do 1671 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 1672 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 1673 | end 1674 | ) 1675 | 1676 | ( 1677 | @deprecated "Use fields_defs()/0 instead" 1678 | @spec defs() :: %{ 1679 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 1680 | } 1681 | def defs() do 1682 | %{ 1683 | 1 => {:id, {:scalar, 0}, :uint64}, 1684 | 2 => {:mapping_id, {:scalar, 0}, :uint64}, 1685 | 3 => {:address, {:scalar, 0}, :uint64}, 1686 | 4 => {:line, :unpacked, {:message, Perftools.Profiles.Line}}, 1687 | 5 => {:is_folded, {:scalar, false}, :bool} 1688 | } 1689 | end 1690 | 1691 | @deprecated "Use fields_defs()/0 instead" 1692 | @spec defs_by_name() :: %{ 1693 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 1694 | } 1695 | def defs_by_name() do 1696 | %{ 1697 | address: {3, {:scalar, 0}, :uint64}, 1698 | id: {1, {:scalar, 0}, :uint64}, 1699 | is_folded: {5, {:scalar, false}, :bool}, 1700 | line: {4, :unpacked, {:message, Perftools.Profiles.Line}}, 1701 | mapping_id: {2, {:scalar, 0}, :uint64} 1702 | } 1703 | end 1704 | ) 1705 | 1706 | ( 1707 | @spec fields_defs() :: list(Protox.Field.t()) 1708 | def fields_defs() do 1709 | [ 1710 | %{ 1711 | __struct__: Protox.Field, 1712 | json_name: "id", 1713 | kind: {:scalar, 0}, 1714 | label: :optional, 1715 | name: :id, 1716 | tag: 1, 1717 | type: :uint64 1718 | }, 1719 | %{ 1720 | __struct__: Protox.Field, 1721 | json_name: "mappingId", 1722 | kind: {:scalar, 0}, 1723 | label: :optional, 1724 | name: :mapping_id, 1725 | tag: 2, 1726 | type: :uint64 1727 | }, 1728 | %{ 1729 | __struct__: Protox.Field, 1730 | json_name: "address", 1731 | kind: {:scalar, 0}, 1732 | label: :optional, 1733 | name: :address, 1734 | tag: 3, 1735 | type: :uint64 1736 | }, 1737 | %{ 1738 | __struct__: Protox.Field, 1739 | json_name: "line", 1740 | kind: :unpacked, 1741 | label: :repeated, 1742 | name: :line, 1743 | tag: 4, 1744 | type: {:message, Perftools.Profiles.Line} 1745 | }, 1746 | %{ 1747 | __struct__: Protox.Field, 1748 | json_name: "isFolded", 1749 | kind: {:scalar, false}, 1750 | label: :optional, 1751 | name: :is_folded, 1752 | tag: 5, 1753 | type: :bool 1754 | } 1755 | ] 1756 | end 1757 | 1758 | [ 1759 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 1760 | ( 1761 | def field_def(:id) do 1762 | {:ok, 1763 | %{ 1764 | __struct__: Protox.Field, 1765 | json_name: "id", 1766 | kind: {:scalar, 0}, 1767 | label: :optional, 1768 | name: :id, 1769 | tag: 1, 1770 | type: :uint64 1771 | }} 1772 | end 1773 | 1774 | def field_def("id") do 1775 | {:ok, 1776 | %{ 1777 | __struct__: Protox.Field, 1778 | json_name: "id", 1779 | kind: {:scalar, 0}, 1780 | label: :optional, 1781 | name: :id, 1782 | tag: 1, 1783 | type: :uint64 1784 | }} 1785 | end 1786 | 1787 | [] 1788 | ), 1789 | ( 1790 | def field_def(:mapping_id) do 1791 | {:ok, 1792 | %{ 1793 | __struct__: Protox.Field, 1794 | json_name: "mappingId", 1795 | kind: {:scalar, 0}, 1796 | label: :optional, 1797 | name: :mapping_id, 1798 | tag: 2, 1799 | type: :uint64 1800 | }} 1801 | end 1802 | 1803 | def field_def("mappingId") do 1804 | {:ok, 1805 | %{ 1806 | __struct__: Protox.Field, 1807 | json_name: "mappingId", 1808 | kind: {:scalar, 0}, 1809 | label: :optional, 1810 | name: :mapping_id, 1811 | tag: 2, 1812 | type: :uint64 1813 | }} 1814 | end 1815 | 1816 | def field_def("mapping_id") do 1817 | {:ok, 1818 | %{ 1819 | __struct__: Protox.Field, 1820 | json_name: "mappingId", 1821 | kind: {:scalar, 0}, 1822 | label: :optional, 1823 | name: :mapping_id, 1824 | tag: 2, 1825 | type: :uint64 1826 | }} 1827 | end 1828 | ), 1829 | ( 1830 | def field_def(:address) do 1831 | {:ok, 1832 | %{ 1833 | __struct__: Protox.Field, 1834 | json_name: "address", 1835 | kind: {:scalar, 0}, 1836 | label: :optional, 1837 | name: :address, 1838 | tag: 3, 1839 | type: :uint64 1840 | }} 1841 | end 1842 | 1843 | def field_def("address") do 1844 | {:ok, 1845 | %{ 1846 | __struct__: Protox.Field, 1847 | json_name: "address", 1848 | kind: {:scalar, 0}, 1849 | label: :optional, 1850 | name: :address, 1851 | tag: 3, 1852 | type: :uint64 1853 | }} 1854 | end 1855 | 1856 | [] 1857 | ), 1858 | ( 1859 | def field_def(:line) do 1860 | {:ok, 1861 | %{ 1862 | __struct__: Protox.Field, 1863 | json_name: "line", 1864 | kind: :unpacked, 1865 | label: :repeated, 1866 | name: :line, 1867 | tag: 4, 1868 | type: {:message, Perftools.Profiles.Line} 1869 | }} 1870 | end 1871 | 1872 | def field_def("line") do 1873 | {:ok, 1874 | %{ 1875 | __struct__: Protox.Field, 1876 | json_name: "line", 1877 | kind: :unpacked, 1878 | label: :repeated, 1879 | name: :line, 1880 | tag: 4, 1881 | type: {:message, Perftools.Profiles.Line} 1882 | }} 1883 | end 1884 | 1885 | [] 1886 | ), 1887 | ( 1888 | def field_def(:is_folded) do 1889 | {:ok, 1890 | %{ 1891 | __struct__: Protox.Field, 1892 | json_name: "isFolded", 1893 | kind: {:scalar, false}, 1894 | label: :optional, 1895 | name: :is_folded, 1896 | tag: 5, 1897 | type: :bool 1898 | }} 1899 | end 1900 | 1901 | def field_def("isFolded") do 1902 | {:ok, 1903 | %{ 1904 | __struct__: Protox.Field, 1905 | json_name: "isFolded", 1906 | kind: {:scalar, false}, 1907 | label: :optional, 1908 | name: :is_folded, 1909 | tag: 5, 1910 | type: :bool 1911 | }} 1912 | end 1913 | 1914 | def field_def("is_folded") do 1915 | {:ok, 1916 | %{ 1917 | __struct__: Protox.Field, 1918 | json_name: "isFolded", 1919 | kind: {:scalar, false}, 1920 | label: :optional, 1921 | name: :is_folded, 1922 | tag: 5, 1923 | type: :bool 1924 | }} 1925 | end 1926 | ), 1927 | def field_def(_) do 1928 | {:error, :no_such_field} 1929 | end 1930 | ] 1931 | ) 1932 | 1933 | ( 1934 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 1935 | def unknown_fields(msg) do 1936 | msg.__uf__ 1937 | end 1938 | 1939 | @spec unknown_fields_name() :: :__uf__ 1940 | def unknown_fields_name() do 1941 | :__uf__ 1942 | end 1943 | 1944 | @spec clear_unknown_fields(struct) :: struct 1945 | def clear_unknown_fields(msg) do 1946 | struct!(msg, [{unknown_fields_name(), []}]) 1947 | end 1948 | ) 1949 | 1950 | ( 1951 | @spec required_fields() :: [] 1952 | def required_fields() do 1953 | [] 1954 | end 1955 | ) 1956 | 1957 | ( 1958 | @spec syntax() :: atom() 1959 | def syntax() do 1960 | :proto3 1961 | end 1962 | ) 1963 | 1964 | [ 1965 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 1966 | def default(:id) do 1967 | {:ok, 0} 1968 | end, 1969 | def default(:mapping_id) do 1970 | {:ok, 0} 1971 | end, 1972 | def default(:address) do 1973 | {:ok, 0} 1974 | end, 1975 | def default(:line) do 1976 | {:error, :no_default_value} 1977 | end, 1978 | def default(:is_folded) do 1979 | {:ok, false} 1980 | end, 1981 | def default(_) do 1982 | {:error, :no_such_field} 1983 | end 1984 | ] 1985 | 1986 | ( 1987 | @spec file_options() :: struct() 1988 | def file_options() do 1989 | file_options = %{ 1990 | __struct__: Protox.Google.Protobuf.FileOptions, 1991 | __uf__: [], 1992 | cc_enable_arenas: nil, 1993 | cc_generic_services: nil, 1994 | csharp_namespace: nil, 1995 | deprecated: nil, 1996 | go_package: nil, 1997 | java_generate_equals_and_hash: nil, 1998 | java_generic_services: nil, 1999 | java_multiple_files: nil, 2000 | java_outer_classname: "ProfileProto", 2001 | java_package: "com.google.perftools.profiles", 2002 | java_string_check_utf8: nil, 2003 | objc_class_prefix: nil, 2004 | optimize_for: nil, 2005 | php_class_prefix: nil, 2006 | php_generic_services: nil, 2007 | php_metadata_namespace: nil, 2008 | php_namespace: nil, 2009 | py_generic_services: nil, 2010 | ruby_package: nil, 2011 | swift_prefix: nil, 2012 | uninterpreted_option: [] 2013 | } 2014 | 2015 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 2016 | true -> 2017 | bytes = 2018 | file_options 2019 | |> Protox.Google.Protobuf.FileOptions.encode!() 2020 | |> :binary.list_to_bin() 2021 | 2022 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 2023 | 2024 | false -> 2025 | file_options 2026 | end 2027 | end 2028 | ) 2029 | end, 2030 | defmodule Perftools.Profiles.Mapping do 2031 | @moduledoc false 2032 | defstruct id: 0, 2033 | memory_start: 0, 2034 | memory_limit: 0, 2035 | file_offset: 0, 2036 | filename: 0, 2037 | build_id: 0, 2038 | has_functions: false, 2039 | has_filenames: false, 2040 | has_line_numbers: false, 2041 | has_inline_frames: false, 2042 | __uf__: [] 2043 | 2044 | ( 2045 | ( 2046 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 2047 | def encode(msg) do 2048 | try do 2049 | {:ok, encode!(msg)} 2050 | rescue 2051 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 2052 | end 2053 | end 2054 | 2055 | @spec encode!(struct) :: iodata | no_return 2056 | def encode!(msg) do 2057 | [] 2058 | |> encode_id(msg) 2059 | |> encode_memory_start(msg) 2060 | |> encode_memory_limit(msg) 2061 | |> encode_file_offset(msg) 2062 | |> encode_filename(msg) 2063 | |> encode_build_id(msg) 2064 | |> encode_has_functions(msg) 2065 | |> encode_has_filenames(msg) 2066 | |> encode_has_line_numbers(msg) 2067 | |> encode_has_inline_frames(msg) 2068 | |> encode_unknown_fields(msg) 2069 | end 2070 | ) 2071 | 2072 | [] 2073 | 2074 | [ 2075 | defp encode_id(acc, msg) do 2076 | try do 2077 | if msg.id == 0 do 2078 | acc 2079 | else 2080 | [acc, "\b", Protox.Encode.encode_uint64(msg.id)] 2081 | end 2082 | rescue 2083 | ArgumentError -> 2084 | reraise Protox.EncodingError.new(:id, "invalid field value"), __STACKTRACE__ 2085 | end 2086 | end, 2087 | defp encode_memory_start(acc, msg) do 2088 | try do 2089 | if msg.memory_start == 0 do 2090 | acc 2091 | else 2092 | [acc, "\x10", Protox.Encode.encode_uint64(msg.memory_start)] 2093 | end 2094 | rescue 2095 | ArgumentError -> 2096 | reraise Protox.EncodingError.new(:memory_start, "invalid field value"), 2097 | __STACKTRACE__ 2098 | end 2099 | end, 2100 | defp encode_memory_limit(acc, msg) do 2101 | try do 2102 | if msg.memory_limit == 0 do 2103 | acc 2104 | else 2105 | [acc, "\x18", Protox.Encode.encode_uint64(msg.memory_limit)] 2106 | end 2107 | rescue 2108 | ArgumentError -> 2109 | reraise Protox.EncodingError.new(:memory_limit, "invalid field value"), 2110 | __STACKTRACE__ 2111 | end 2112 | end, 2113 | defp encode_file_offset(acc, msg) do 2114 | try do 2115 | if msg.file_offset == 0 do 2116 | acc 2117 | else 2118 | [acc, " ", Protox.Encode.encode_uint64(msg.file_offset)] 2119 | end 2120 | rescue 2121 | ArgumentError -> 2122 | reraise Protox.EncodingError.new(:file_offset, "invalid field value"), 2123 | __STACKTRACE__ 2124 | end 2125 | end, 2126 | defp encode_filename(acc, msg) do 2127 | try do 2128 | if msg.filename == 0 do 2129 | acc 2130 | else 2131 | [acc, "(", Protox.Encode.encode_int64(msg.filename)] 2132 | end 2133 | rescue 2134 | ArgumentError -> 2135 | reraise Protox.EncodingError.new(:filename, "invalid field value"), __STACKTRACE__ 2136 | end 2137 | end, 2138 | defp encode_build_id(acc, msg) do 2139 | try do 2140 | if msg.build_id == 0 do 2141 | acc 2142 | else 2143 | [acc, "0", Protox.Encode.encode_int64(msg.build_id)] 2144 | end 2145 | rescue 2146 | ArgumentError -> 2147 | reraise Protox.EncodingError.new(:build_id, "invalid field value"), __STACKTRACE__ 2148 | end 2149 | end, 2150 | defp encode_has_functions(acc, msg) do 2151 | try do 2152 | if msg.has_functions == false do 2153 | acc 2154 | else 2155 | [acc, "8", Protox.Encode.encode_bool(msg.has_functions)] 2156 | end 2157 | rescue 2158 | ArgumentError -> 2159 | reraise Protox.EncodingError.new(:has_functions, "invalid field value"), 2160 | __STACKTRACE__ 2161 | end 2162 | end, 2163 | defp encode_has_filenames(acc, msg) do 2164 | try do 2165 | if msg.has_filenames == false do 2166 | acc 2167 | else 2168 | [acc, "@", Protox.Encode.encode_bool(msg.has_filenames)] 2169 | end 2170 | rescue 2171 | ArgumentError -> 2172 | reraise Protox.EncodingError.new(:has_filenames, "invalid field value"), 2173 | __STACKTRACE__ 2174 | end 2175 | end, 2176 | defp encode_has_line_numbers(acc, msg) do 2177 | try do 2178 | if msg.has_line_numbers == false do 2179 | acc 2180 | else 2181 | [acc, "H", Protox.Encode.encode_bool(msg.has_line_numbers)] 2182 | end 2183 | rescue 2184 | ArgumentError -> 2185 | reraise Protox.EncodingError.new(:has_line_numbers, "invalid field value"), 2186 | __STACKTRACE__ 2187 | end 2188 | end, 2189 | defp encode_has_inline_frames(acc, msg) do 2190 | try do 2191 | if msg.has_inline_frames == false do 2192 | acc 2193 | else 2194 | [acc, "P", Protox.Encode.encode_bool(msg.has_inline_frames)] 2195 | end 2196 | rescue 2197 | ArgumentError -> 2198 | reraise Protox.EncodingError.new(:has_inline_frames, "invalid field value"), 2199 | __STACKTRACE__ 2200 | end 2201 | end 2202 | ] 2203 | 2204 | defp encode_unknown_fields(acc, msg) do 2205 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 2206 | case wire_type do 2207 | 0 -> 2208 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 2209 | 2210 | 1 -> 2211 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 2212 | 2213 | 2 -> 2214 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 2215 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 2216 | 2217 | 5 -> 2218 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 2219 | end 2220 | end) 2221 | end 2222 | ) 2223 | 2224 | ( 2225 | ( 2226 | @spec decode(binary) :: {:ok, struct} | {:error, any} 2227 | def decode(bytes) do 2228 | try do 2229 | {:ok, decode!(bytes)} 2230 | rescue 2231 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 2232 | {:error, e} 2233 | end 2234 | end 2235 | 2236 | ( 2237 | @spec decode!(binary) :: struct | no_return 2238 | def decode!(bytes) do 2239 | parse_key_value(bytes, struct(Perftools.Profiles.Mapping)) 2240 | end 2241 | ) 2242 | ) 2243 | 2244 | ( 2245 | @spec parse_key_value(binary, struct) :: struct 2246 | defp parse_key_value(<<>>, msg) do 2247 | msg 2248 | end 2249 | 2250 | defp parse_key_value(bytes, msg) do 2251 | {field, rest} = 2252 | case Protox.Decode.parse_key(bytes) do 2253 | {0, _, _} -> 2254 | raise %Protox.IllegalTagError{} 2255 | 2256 | {1, _, bytes} -> 2257 | {value, rest} = Protox.Decode.parse_uint64(bytes) 2258 | {[id: value], rest} 2259 | 2260 | {2, _, bytes} -> 2261 | {value, rest} = Protox.Decode.parse_uint64(bytes) 2262 | {[memory_start: value], rest} 2263 | 2264 | {3, _, bytes} -> 2265 | {value, rest} = Protox.Decode.parse_uint64(bytes) 2266 | {[memory_limit: value], rest} 2267 | 2268 | {4, _, bytes} -> 2269 | {value, rest} = Protox.Decode.parse_uint64(bytes) 2270 | {[file_offset: value], rest} 2271 | 2272 | {5, _, bytes} -> 2273 | {value, rest} = Protox.Decode.parse_int64(bytes) 2274 | {[filename: value], rest} 2275 | 2276 | {6, _, bytes} -> 2277 | {value, rest} = Protox.Decode.parse_int64(bytes) 2278 | {[build_id: value], rest} 2279 | 2280 | {7, _, bytes} -> 2281 | {value, rest} = Protox.Decode.parse_bool(bytes) 2282 | {[has_functions: value], rest} 2283 | 2284 | {8, _, bytes} -> 2285 | {value, rest} = Protox.Decode.parse_bool(bytes) 2286 | {[has_filenames: value], rest} 2287 | 2288 | {9, _, bytes} -> 2289 | {value, rest} = Protox.Decode.parse_bool(bytes) 2290 | {[has_line_numbers: value], rest} 2291 | 2292 | {10, _, bytes} -> 2293 | {value, rest} = Protox.Decode.parse_bool(bytes) 2294 | {[has_inline_frames: value], rest} 2295 | 2296 | {tag, wire_type, rest} -> 2297 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 2298 | 2299 | {[ 2300 | {msg.__struct__.unknown_fields_name, 2301 | [value | msg.__struct__.unknown_fields(msg)]} 2302 | ], rest} 2303 | end 2304 | 2305 | msg_updated = struct(msg, field) 2306 | parse_key_value(rest, msg_updated) 2307 | end 2308 | ) 2309 | 2310 | [] 2311 | ) 2312 | 2313 | ( 2314 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 2315 | def json_decode(input, opts \\ []) do 2316 | try do 2317 | {:ok, json_decode!(input, opts)} 2318 | rescue 2319 | e in Protox.JsonDecodingError -> {:error, e} 2320 | end 2321 | end 2322 | 2323 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 2324 | def json_decode!(input, opts \\ []) do 2325 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 2326 | 2327 | Protox.JsonDecode.decode!( 2328 | input, 2329 | Perftools.Profiles.Mapping, 2330 | &json_library_wrapper.decode!(json_library, &1) 2331 | ) 2332 | end 2333 | 2334 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 2335 | def json_encode(msg, opts \\ []) do 2336 | try do 2337 | {:ok, json_encode!(msg, opts)} 2338 | rescue 2339 | e in Protox.JsonEncodingError -> {:error, e} 2340 | end 2341 | end 2342 | 2343 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 2344 | def json_encode!(msg, opts \\ []) do 2345 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 2346 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 2347 | end 2348 | ) 2349 | 2350 | ( 2351 | @deprecated "Use fields_defs()/0 instead" 2352 | @spec defs() :: %{ 2353 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 2354 | } 2355 | def defs() do 2356 | %{ 2357 | 1 => {:id, {:scalar, 0}, :uint64}, 2358 | 2 => {:memory_start, {:scalar, 0}, :uint64}, 2359 | 3 => {:memory_limit, {:scalar, 0}, :uint64}, 2360 | 4 => {:file_offset, {:scalar, 0}, :uint64}, 2361 | 5 => {:filename, {:scalar, 0}, :int64}, 2362 | 6 => {:build_id, {:scalar, 0}, :int64}, 2363 | 7 => {:has_functions, {:scalar, false}, :bool}, 2364 | 8 => {:has_filenames, {:scalar, false}, :bool}, 2365 | 9 => {:has_line_numbers, {:scalar, false}, :bool}, 2366 | 10 => {:has_inline_frames, {:scalar, false}, :bool} 2367 | } 2368 | end 2369 | 2370 | @deprecated "Use fields_defs()/0 instead" 2371 | @spec defs_by_name() :: %{ 2372 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 2373 | } 2374 | def defs_by_name() do 2375 | %{ 2376 | build_id: {6, {:scalar, 0}, :int64}, 2377 | file_offset: {4, {:scalar, 0}, :uint64}, 2378 | filename: {5, {:scalar, 0}, :int64}, 2379 | has_filenames: {8, {:scalar, false}, :bool}, 2380 | has_functions: {7, {:scalar, false}, :bool}, 2381 | has_inline_frames: {10, {:scalar, false}, :bool}, 2382 | has_line_numbers: {9, {:scalar, false}, :bool}, 2383 | id: {1, {:scalar, 0}, :uint64}, 2384 | memory_limit: {3, {:scalar, 0}, :uint64}, 2385 | memory_start: {2, {:scalar, 0}, :uint64} 2386 | } 2387 | end 2388 | ) 2389 | 2390 | ( 2391 | @spec fields_defs() :: list(Protox.Field.t()) 2392 | def fields_defs() do 2393 | [ 2394 | %{ 2395 | __struct__: Protox.Field, 2396 | json_name: "id", 2397 | kind: {:scalar, 0}, 2398 | label: :optional, 2399 | name: :id, 2400 | tag: 1, 2401 | type: :uint64 2402 | }, 2403 | %{ 2404 | __struct__: Protox.Field, 2405 | json_name: "memoryStart", 2406 | kind: {:scalar, 0}, 2407 | label: :optional, 2408 | name: :memory_start, 2409 | tag: 2, 2410 | type: :uint64 2411 | }, 2412 | %{ 2413 | __struct__: Protox.Field, 2414 | json_name: "memoryLimit", 2415 | kind: {:scalar, 0}, 2416 | label: :optional, 2417 | name: :memory_limit, 2418 | tag: 3, 2419 | type: :uint64 2420 | }, 2421 | %{ 2422 | __struct__: Protox.Field, 2423 | json_name: "fileOffset", 2424 | kind: {:scalar, 0}, 2425 | label: :optional, 2426 | name: :file_offset, 2427 | tag: 4, 2428 | type: :uint64 2429 | }, 2430 | %{ 2431 | __struct__: Protox.Field, 2432 | json_name: "filename", 2433 | kind: {:scalar, 0}, 2434 | label: :optional, 2435 | name: :filename, 2436 | tag: 5, 2437 | type: :int64 2438 | }, 2439 | %{ 2440 | __struct__: Protox.Field, 2441 | json_name: "buildId", 2442 | kind: {:scalar, 0}, 2443 | label: :optional, 2444 | name: :build_id, 2445 | tag: 6, 2446 | type: :int64 2447 | }, 2448 | %{ 2449 | __struct__: Protox.Field, 2450 | json_name: "hasFunctions", 2451 | kind: {:scalar, false}, 2452 | label: :optional, 2453 | name: :has_functions, 2454 | tag: 7, 2455 | type: :bool 2456 | }, 2457 | %{ 2458 | __struct__: Protox.Field, 2459 | json_name: "hasFilenames", 2460 | kind: {:scalar, false}, 2461 | label: :optional, 2462 | name: :has_filenames, 2463 | tag: 8, 2464 | type: :bool 2465 | }, 2466 | %{ 2467 | __struct__: Protox.Field, 2468 | json_name: "hasLineNumbers", 2469 | kind: {:scalar, false}, 2470 | label: :optional, 2471 | name: :has_line_numbers, 2472 | tag: 9, 2473 | type: :bool 2474 | }, 2475 | %{ 2476 | __struct__: Protox.Field, 2477 | json_name: "hasInlineFrames", 2478 | kind: {:scalar, false}, 2479 | label: :optional, 2480 | name: :has_inline_frames, 2481 | tag: 10, 2482 | type: :bool 2483 | } 2484 | ] 2485 | end 2486 | 2487 | [ 2488 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 2489 | ( 2490 | def field_def(:id) do 2491 | {:ok, 2492 | %{ 2493 | __struct__: Protox.Field, 2494 | json_name: "id", 2495 | kind: {:scalar, 0}, 2496 | label: :optional, 2497 | name: :id, 2498 | tag: 1, 2499 | type: :uint64 2500 | }} 2501 | end 2502 | 2503 | def field_def("id") do 2504 | {:ok, 2505 | %{ 2506 | __struct__: Protox.Field, 2507 | json_name: "id", 2508 | kind: {:scalar, 0}, 2509 | label: :optional, 2510 | name: :id, 2511 | tag: 1, 2512 | type: :uint64 2513 | }} 2514 | end 2515 | 2516 | [] 2517 | ), 2518 | ( 2519 | def field_def(:memory_start) do 2520 | {:ok, 2521 | %{ 2522 | __struct__: Protox.Field, 2523 | json_name: "memoryStart", 2524 | kind: {:scalar, 0}, 2525 | label: :optional, 2526 | name: :memory_start, 2527 | tag: 2, 2528 | type: :uint64 2529 | }} 2530 | end 2531 | 2532 | def field_def("memoryStart") do 2533 | {:ok, 2534 | %{ 2535 | __struct__: Protox.Field, 2536 | json_name: "memoryStart", 2537 | kind: {:scalar, 0}, 2538 | label: :optional, 2539 | name: :memory_start, 2540 | tag: 2, 2541 | type: :uint64 2542 | }} 2543 | end 2544 | 2545 | def field_def("memory_start") do 2546 | {:ok, 2547 | %{ 2548 | __struct__: Protox.Field, 2549 | json_name: "memoryStart", 2550 | kind: {:scalar, 0}, 2551 | label: :optional, 2552 | name: :memory_start, 2553 | tag: 2, 2554 | type: :uint64 2555 | }} 2556 | end 2557 | ), 2558 | ( 2559 | def field_def(:memory_limit) do 2560 | {:ok, 2561 | %{ 2562 | __struct__: Protox.Field, 2563 | json_name: "memoryLimit", 2564 | kind: {:scalar, 0}, 2565 | label: :optional, 2566 | name: :memory_limit, 2567 | tag: 3, 2568 | type: :uint64 2569 | }} 2570 | end 2571 | 2572 | def field_def("memoryLimit") do 2573 | {:ok, 2574 | %{ 2575 | __struct__: Protox.Field, 2576 | json_name: "memoryLimit", 2577 | kind: {:scalar, 0}, 2578 | label: :optional, 2579 | name: :memory_limit, 2580 | tag: 3, 2581 | type: :uint64 2582 | }} 2583 | end 2584 | 2585 | def field_def("memory_limit") do 2586 | {:ok, 2587 | %{ 2588 | __struct__: Protox.Field, 2589 | json_name: "memoryLimit", 2590 | kind: {:scalar, 0}, 2591 | label: :optional, 2592 | name: :memory_limit, 2593 | tag: 3, 2594 | type: :uint64 2595 | }} 2596 | end 2597 | ), 2598 | ( 2599 | def field_def(:file_offset) do 2600 | {:ok, 2601 | %{ 2602 | __struct__: Protox.Field, 2603 | json_name: "fileOffset", 2604 | kind: {:scalar, 0}, 2605 | label: :optional, 2606 | name: :file_offset, 2607 | tag: 4, 2608 | type: :uint64 2609 | }} 2610 | end 2611 | 2612 | def field_def("fileOffset") do 2613 | {:ok, 2614 | %{ 2615 | __struct__: Protox.Field, 2616 | json_name: "fileOffset", 2617 | kind: {:scalar, 0}, 2618 | label: :optional, 2619 | name: :file_offset, 2620 | tag: 4, 2621 | type: :uint64 2622 | }} 2623 | end 2624 | 2625 | def field_def("file_offset") do 2626 | {:ok, 2627 | %{ 2628 | __struct__: Protox.Field, 2629 | json_name: "fileOffset", 2630 | kind: {:scalar, 0}, 2631 | label: :optional, 2632 | name: :file_offset, 2633 | tag: 4, 2634 | type: :uint64 2635 | }} 2636 | end 2637 | ), 2638 | ( 2639 | def field_def(:filename) do 2640 | {:ok, 2641 | %{ 2642 | __struct__: Protox.Field, 2643 | json_name: "filename", 2644 | kind: {:scalar, 0}, 2645 | label: :optional, 2646 | name: :filename, 2647 | tag: 5, 2648 | type: :int64 2649 | }} 2650 | end 2651 | 2652 | def field_def("filename") do 2653 | {:ok, 2654 | %{ 2655 | __struct__: Protox.Field, 2656 | json_name: "filename", 2657 | kind: {:scalar, 0}, 2658 | label: :optional, 2659 | name: :filename, 2660 | tag: 5, 2661 | type: :int64 2662 | }} 2663 | end 2664 | 2665 | [] 2666 | ), 2667 | ( 2668 | def field_def(:build_id) do 2669 | {:ok, 2670 | %{ 2671 | __struct__: Protox.Field, 2672 | json_name: "buildId", 2673 | kind: {:scalar, 0}, 2674 | label: :optional, 2675 | name: :build_id, 2676 | tag: 6, 2677 | type: :int64 2678 | }} 2679 | end 2680 | 2681 | def field_def("buildId") do 2682 | {:ok, 2683 | %{ 2684 | __struct__: Protox.Field, 2685 | json_name: "buildId", 2686 | kind: {:scalar, 0}, 2687 | label: :optional, 2688 | name: :build_id, 2689 | tag: 6, 2690 | type: :int64 2691 | }} 2692 | end 2693 | 2694 | def field_def("build_id") do 2695 | {:ok, 2696 | %{ 2697 | __struct__: Protox.Field, 2698 | json_name: "buildId", 2699 | kind: {:scalar, 0}, 2700 | label: :optional, 2701 | name: :build_id, 2702 | tag: 6, 2703 | type: :int64 2704 | }} 2705 | end 2706 | ), 2707 | ( 2708 | def field_def(:has_functions) do 2709 | {:ok, 2710 | %{ 2711 | __struct__: Protox.Field, 2712 | json_name: "hasFunctions", 2713 | kind: {:scalar, false}, 2714 | label: :optional, 2715 | name: :has_functions, 2716 | tag: 7, 2717 | type: :bool 2718 | }} 2719 | end 2720 | 2721 | def field_def("hasFunctions") do 2722 | {:ok, 2723 | %{ 2724 | __struct__: Protox.Field, 2725 | json_name: "hasFunctions", 2726 | kind: {:scalar, false}, 2727 | label: :optional, 2728 | name: :has_functions, 2729 | tag: 7, 2730 | type: :bool 2731 | }} 2732 | end 2733 | 2734 | def field_def("has_functions") do 2735 | {:ok, 2736 | %{ 2737 | __struct__: Protox.Field, 2738 | json_name: "hasFunctions", 2739 | kind: {:scalar, false}, 2740 | label: :optional, 2741 | name: :has_functions, 2742 | tag: 7, 2743 | type: :bool 2744 | }} 2745 | end 2746 | ), 2747 | ( 2748 | def field_def(:has_filenames) do 2749 | {:ok, 2750 | %{ 2751 | __struct__: Protox.Field, 2752 | json_name: "hasFilenames", 2753 | kind: {:scalar, false}, 2754 | label: :optional, 2755 | name: :has_filenames, 2756 | tag: 8, 2757 | type: :bool 2758 | }} 2759 | end 2760 | 2761 | def field_def("hasFilenames") do 2762 | {:ok, 2763 | %{ 2764 | __struct__: Protox.Field, 2765 | json_name: "hasFilenames", 2766 | kind: {:scalar, false}, 2767 | label: :optional, 2768 | name: :has_filenames, 2769 | tag: 8, 2770 | type: :bool 2771 | }} 2772 | end 2773 | 2774 | def field_def("has_filenames") do 2775 | {:ok, 2776 | %{ 2777 | __struct__: Protox.Field, 2778 | json_name: "hasFilenames", 2779 | kind: {:scalar, false}, 2780 | label: :optional, 2781 | name: :has_filenames, 2782 | tag: 8, 2783 | type: :bool 2784 | }} 2785 | end 2786 | ), 2787 | ( 2788 | def field_def(:has_line_numbers) do 2789 | {:ok, 2790 | %{ 2791 | __struct__: Protox.Field, 2792 | json_name: "hasLineNumbers", 2793 | kind: {:scalar, false}, 2794 | label: :optional, 2795 | name: :has_line_numbers, 2796 | tag: 9, 2797 | type: :bool 2798 | }} 2799 | end 2800 | 2801 | def field_def("hasLineNumbers") do 2802 | {:ok, 2803 | %{ 2804 | __struct__: Protox.Field, 2805 | json_name: "hasLineNumbers", 2806 | kind: {:scalar, false}, 2807 | label: :optional, 2808 | name: :has_line_numbers, 2809 | tag: 9, 2810 | type: :bool 2811 | }} 2812 | end 2813 | 2814 | def field_def("has_line_numbers") do 2815 | {:ok, 2816 | %{ 2817 | __struct__: Protox.Field, 2818 | json_name: "hasLineNumbers", 2819 | kind: {:scalar, false}, 2820 | label: :optional, 2821 | name: :has_line_numbers, 2822 | tag: 9, 2823 | type: :bool 2824 | }} 2825 | end 2826 | ), 2827 | ( 2828 | def field_def(:has_inline_frames) do 2829 | {:ok, 2830 | %{ 2831 | __struct__: Protox.Field, 2832 | json_name: "hasInlineFrames", 2833 | kind: {:scalar, false}, 2834 | label: :optional, 2835 | name: :has_inline_frames, 2836 | tag: 10, 2837 | type: :bool 2838 | }} 2839 | end 2840 | 2841 | def field_def("hasInlineFrames") do 2842 | {:ok, 2843 | %{ 2844 | __struct__: Protox.Field, 2845 | json_name: "hasInlineFrames", 2846 | kind: {:scalar, false}, 2847 | label: :optional, 2848 | name: :has_inline_frames, 2849 | tag: 10, 2850 | type: :bool 2851 | }} 2852 | end 2853 | 2854 | def field_def("has_inline_frames") do 2855 | {:ok, 2856 | %{ 2857 | __struct__: Protox.Field, 2858 | json_name: "hasInlineFrames", 2859 | kind: {:scalar, false}, 2860 | label: :optional, 2861 | name: :has_inline_frames, 2862 | tag: 10, 2863 | type: :bool 2864 | }} 2865 | end 2866 | ), 2867 | def field_def(_) do 2868 | {:error, :no_such_field} 2869 | end 2870 | ] 2871 | ) 2872 | 2873 | ( 2874 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 2875 | def unknown_fields(msg) do 2876 | msg.__uf__ 2877 | end 2878 | 2879 | @spec unknown_fields_name() :: :__uf__ 2880 | def unknown_fields_name() do 2881 | :__uf__ 2882 | end 2883 | 2884 | @spec clear_unknown_fields(struct) :: struct 2885 | def clear_unknown_fields(msg) do 2886 | struct!(msg, [{unknown_fields_name(), []}]) 2887 | end 2888 | ) 2889 | 2890 | ( 2891 | @spec required_fields() :: [] 2892 | def required_fields() do 2893 | [] 2894 | end 2895 | ) 2896 | 2897 | ( 2898 | @spec syntax() :: atom() 2899 | def syntax() do 2900 | :proto3 2901 | end 2902 | ) 2903 | 2904 | [ 2905 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 2906 | def default(:id) do 2907 | {:ok, 0} 2908 | end, 2909 | def default(:memory_start) do 2910 | {:ok, 0} 2911 | end, 2912 | def default(:memory_limit) do 2913 | {:ok, 0} 2914 | end, 2915 | def default(:file_offset) do 2916 | {:ok, 0} 2917 | end, 2918 | def default(:filename) do 2919 | {:ok, 0} 2920 | end, 2921 | def default(:build_id) do 2922 | {:ok, 0} 2923 | end, 2924 | def default(:has_functions) do 2925 | {:ok, false} 2926 | end, 2927 | def default(:has_filenames) do 2928 | {:ok, false} 2929 | end, 2930 | def default(:has_line_numbers) do 2931 | {:ok, false} 2932 | end, 2933 | def default(:has_inline_frames) do 2934 | {:ok, false} 2935 | end, 2936 | def default(_) do 2937 | {:error, :no_such_field} 2938 | end 2939 | ] 2940 | 2941 | ( 2942 | @spec file_options() :: struct() 2943 | def file_options() do 2944 | file_options = %{ 2945 | __struct__: Protox.Google.Protobuf.FileOptions, 2946 | __uf__: [], 2947 | cc_enable_arenas: nil, 2948 | cc_generic_services: nil, 2949 | csharp_namespace: nil, 2950 | deprecated: nil, 2951 | go_package: nil, 2952 | java_generate_equals_and_hash: nil, 2953 | java_generic_services: nil, 2954 | java_multiple_files: nil, 2955 | java_outer_classname: "ProfileProto", 2956 | java_package: "com.google.perftools.profiles", 2957 | java_string_check_utf8: nil, 2958 | objc_class_prefix: nil, 2959 | optimize_for: nil, 2960 | php_class_prefix: nil, 2961 | php_generic_services: nil, 2962 | php_metadata_namespace: nil, 2963 | php_namespace: nil, 2964 | py_generic_services: nil, 2965 | ruby_package: nil, 2966 | swift_prefix: nil, 2967 | uninterpreted_option: [] 2968 | } 2969 | 2970 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 2971 | true -> 2972 | bytes = 2973 | file_options 2974 | |> Protox.Google.Protobuf.FileOptions.encode!() 2975 | |> :binary.list_to_bin() 2976 | 2977 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 2978 | 2979 | false -> 2980 | file_options 2981 | end 2982 | end 2983 | ) 2984 | end, 2985 | defmodule Perftools.Profiles.Profile do 2986 | @moduledoc false 2987 | defstruct sample_type: [], 2988 | sample: [], 2989 | mapping: [], 2990 | location: [], 2991 | function: [], 2992 | string_table: [], 2993 | drop_frames: 0, 2994 | keep_frames: 0, 2995 | time_nanos: 0, 2996 | duration_nanos: 0, 2997 | period_type: nil, 2998 | period: 0, 2999 | comment: [], 3000 | default_sample_type: 0, 3001 | __uf__: [] 3002 | 3003 | ( 3004 | ( 3005 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 3006 | def encode(msg) do 3007 | try do 3008 | {:ok, encode!(msg)} 3009 | rescue 3010 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 3011 | end 3012 | end 3013 | 3014 | @spec encode!(struct) :: iodata | no_return 3015 | def encode!(msg) do 3016 | [] 3017 | |> encode_sample_type(msg) 3018 | |> encode_sample(msg) 3019 | |> encode_mapping(msg) 3020 | |> encode_location(msg) 3021 | |> encode_function(msg) 3022 | |> encode_string_table(msg) 3023 | |> encode_drop_frames(msg) 3024 | |> encode_keep_frames(msg) 3025 | |> encode_time_nanos(msg) 3026 | |> encode_duration_nanos(msg) 3027 | |> encode_period_type(msg) 3028 | |> encode_period(msg) 3029 | |> encode_comment(msg) 3030 | |> encode_default_sample_type(msg) 3031 | |> encode_unknown_fields(msg) 3032 | end 3033 | ) 3034 | 3035 | [] 3036 | 3037 | [ 3038 | defp encode_sample_type(acc, msg) do 3039 | try do 3040 | case msg.sample_type do 3041 | [] -> 3042 | acc 3043 | 3044 | values -> 3045 | [ 3046 | acc, 3047 | Enum.reduce(values, [], fn value, acc -> 3048 | [acc, "\n", Protox.Encode.encode_message(value)] 3049 | end) 3050 | ] 3051 | end 3052 | rescue 3053 | ArgumentError -> 3054 | reraise Protox.EncodingError.new(:sample_type, "invalid field value"), 3055 | __STACKTRACE__ 3056 | end 3057 | end, 3058 | defp encode_sample(acc, msg) do 3059 | try do 3060 | case msg.sample do 3061 | [] -> 3062 | acc 3063 | 3064 | values -> 3065 | [ 3066 | acc, 3067 | Enum.reduce(values, [], fn value, acc -> 3068 | [acc, "\x12", Protox.Encode.encode_message(value)] 3069 | end) 3070 | ] 3071 | end 3072 | rescue 3073 | ArgumentError -> 3074 | reraise Protox.EncodingError.new(:sample, "invalid field value"), __STACKTRACE__ 3075 | end 3076 | end, 3077 | defp encode_mapping(acc, msg) do 3078 | try do 3079 | case msg.mapping do 3080 | [] -> 3081 | acc 3082 | 3083 | values -> 3084 | [ 3085 | acc, 3086 | Enum.reduce(values, [], fn value, acc -> 3087 | [acc, "\x1A", Protox.Encode.encode_message(value)] 3088 | end) 3089 | ] 3090 | end 3091 | rescue 3092 | ArgumentError -> 3093 | reraise Protox.EncodingError.new(:mapping, "invalid field value"), __STACKTRACE__ 3094 | end 3095 | end, 3096 | defp encode_location(acc, msg) do 3097 | try do 3098 | case msg.location do 3099 | [] -> 3100 | acc 3101 | 3102 | values -> 3103 | [ 3104 | acc, 3105 | Enum.reduce(values, [], fn value, acc -> 3106 | [acc, "\"", Protox.Encode.encode_message(value)] 3107 | end) 3108 | ] 3109 | end 3110 | rescue 3111 | ArgumentError -> 3112 | reraise Protox.EncodingError.new(:location, "invalid field value"), __STACKTRACE__ 3113 | end 3114 | end, 3115 | defp encode_function(acc, msg) do 3116 | try do 3117 | case msg.function do 3118 | [] -> 3119 | acc 3120 | 3121 | values -> 3122 | [ 3123 | acc, 3124 | Enum.reduce(values, [], fn value, acc -> 3125 | [acc, "*", Protox.Encode.encode_message(value)] 3126 | end) 3127 | ] 3128 | end 3129 | rescue 3130 | ArgumentError -> 3131 | reraise Protox.EncodingError.new(:function, "invalid field value"), __STACKTRACE__ 3132 | end 3133 | end, 3134 | defp encode_string_table(acc, msg) do 3135 | try do 3136 | case msg.string_table do 3137 | [] -> 3138 | acc 3139 | 3140 | values -> 3141 | [ 3142 | acc, 3143 | Enum.reduce(values, [], fn value, acc -> 3144 | [acc, "2", Protox.Encode.encode_string(value)] 3145 | end) 3146 | ] 3147 | end 3148 | rescue 3149 | ArgumentError -> 3150 | reraise Protox.EncodingError.new(:string_table, "invalid field value"), 3151 | __STACKTRACE__ 3152 | end 3153 | end, 3154 | defp encode_drop_frames(acc, msg) do 3155 | try do 3156 | if msg.drop_frames == 0 do 3157 | acc 3158 | else 3159 | [acc, "8", Protox.Encode.encode_int64(msg.drop_frames)] 3160 | end 3161 | rescue 3162 | ArgumentError -> 3163 | reraise Protox.EncodingError.new(:drop_frames, "invalid field value"), 3164 | __STACKTRACE__ 3165 | end 3166 | end, 3167 | defp encode_keep_frames(acc, msg) do 3168 | try do 3169 | if msg.keep_frames == 0 do 3170 | acc 3171 | else 3172 | [acc, "@", Protox.Encode.encode_int64(msg.keep_frames)] 3173 | end 3174 | rescue 3175 | ArgumentError -> 3176 | reraise Protox.EncodingError.new(:keep_frames, "invalid field value"), 3177 | __STACKTRACE__ 3178 | end 3179 | end, 3180 | defp encode_time_nanos(acc, msg) do 3181 | try do 3182 | if msg.time_nanos == 0 do 3183 | acc 3184 | else 3185 | [acc, "H", Protox.Encode.encode_int64(msg.time_nanos)] 3186 | end 3187 | rescue 3188 | ArgumentError -> 3189 | reraise Protox.EncodingError.new(:time_nanos, "invalid field value"), __STACKTRACE__ 3190 | end 3191 | end, 3192 | defp encode_duration_nanos(acc, msg) do 3193 | try do 3194 | if msg.duration_nanos == 0 do 3195 | acc 3196 | else 3197 | [acc, "P", Protox.Encode.encode_int64(msg.duration_nanos)] 3198 | end 3199 | rescue 3200 | ArgumentError -> 3201 | reraise Protox.EncodingError.new(:duration_nanos, "invalid field value"), 3202 | __STACKTRACE__ 3203 | end 3204 | end, 3205 | defp encode_period_type(acc, msg) do 3206 | try do 3207 | if msg.period_type == nil do 3208 | acc 3209 | else 3210 | [acc, "Z", Protox.Encode.encode_message(msg.period_type)] 3211 | end 3212 | rescue 3213 | ArgumentError -> 3214 | reraise Protox.EncodingError.new(:period_type, "invalid field value"), 3215 | __STACKTRACE__ 3216 | end 3217 | end, 3218 | defp encode_period(acc, msg) do 3219 | try do 3220 | if msg.period == 0 do 3221 | acc 3222 | else 3223 | [acc, "`", Protox.Encode.encode_int64(msg.period)] 3224 | end 3225 | rescue 3226 | ArgumentError -> 3227 | reraise Protox.EncodingError.new(:period, "invalid field value"), __STACKTRACE__ 3228 | end 3229 | end, 3230 | defp encode_comment(acc, msg) do 3231 | try do 3232 | case msg.comment do 3233 | [] -> 3234 | acc 3235 | 3236 | values -> 3237 | [ 3238 | acc, 3239 | "j", 3240 | ( 3241 | {bytes, len} = 3242 | Enum.reduce(values, {[], 0}, fn value, {acc, len} -> 3243 | value_bytes = :binary.list_to_bin([Protox.Encode.encode_int64(value)]) 3244 | {[acc, value_bytes], len + byte_size(value_bytes)} 3245 | end) 3246 | 3247 | [Protox.Varint.encode(len), bytes] 3248 | ) 3249 | ] 3250 | end 3251 | rescue 3252 | ArgumentError -> 3253 | reraise Protox.EncodingError.new(:comment, "invalid field value"), __STACKTRACE__ 3254 | end 3255 | end, 3256 | defp encode_default_sample_type(acc, msg) do 3257 | try do 3258 | if msg.default_sample_type == 0 do 3259 | acc 3260 | else 3261 | [acc, "p", Protox.Encode.encode_int64(msg.default_sample_type)] 3262 | end 3263 | rescue 3264 | ArgumentError -> 3265 | reraise Protox.EncodingError.new(:default_sample_type, "invalid field value"), 3266 | __STACKTRACE__ 3267 | end 3268 | end 3269 | ] 3270 | 3271 | defp encode_unknown_fields(acc, msg) do 3272 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 3273 | case wire_type do 3274 | 0 -> 3275 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 3276 | 3277 | 1 -> 3278 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 3279 | 3280 | 2 -> 3281 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 3282 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 3283 | 3284 | 5 -> 3285 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 3286 | end 3287 | end) 3288 | end 3289 | ) 3290 | 3291 | ( 3292 | ( 3293 | @spec decode(binary) :: {:ok, struct} | {:error, any} 3294 | def decode(bytes) do 3295 | try do 3296 | {:ok, decode!(bytes)} 3297 | rescue 3298 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 3299 | {:error, e} 3300 | end 3301 | end 3302 | 3303 | ( 3304 | @spec decode!(binary) :: struct | no_return 3305 | def decode!(bytes) do 3306 | parse_key_value(bytes, struct(Perftools.Profiles.Profile)) 3307 | end 3308 | ) 3309 | ) 3310 | 3311 | ( 3312 | @spec parse_key_value(binary, struct) :: struct 3313 | defp parse_key_value(<<>>, msg) do 3314 | msg 3315 | end 3316 | 3317 | defp parse_key_value(bytes, msg) do 3318 | {field, rest} = 3319 | case Protox.Decode.parse_key(bytes) do 3320 | {0, _, _} -> 3321 | raise %Protox.IllegalTagError{} 3322 | 3323 | {1, _, bytes} -> 3324 | {len, bytes} = Protox.Varint.decode(bytes) 3325 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3326 | 3327 | {[ 3328 | sample_type: 3329 | msg.sample_type ++ [Perftools.Profiles.ValueType.decode!(delimited)] 3330 | ], rest} 3331 | 3332 | {2, _, bytes} -> 3333 | {len, bytes} = Protox.Varint.decode(bytes) 3334 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3335 | {[sample: msg.sample ++ [Perftools.Profiles.Sample.decode!(delimited)]], rest} 3336 | 3337 | {3, _, bytes} -> 3338 | {len, bytes} = Protox.Varint.decode(bytes) 3339 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3340 | {[mapping: msg.mapping ++ [Perftools.Profiles.Mapping.decode!(delimited)]], rest} 3341 | 3342 | {4, _, bytes} -> 3343 | {len, bytes} = Protox.Varint.decode(bytes) 3344 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3345 | 3346 | {[location: msg.location ++ [Perftools.Profiles.Location.decode!(delimited)]], 3347 | rest} 3348 | 3349 | {5, _, bytes} -> 3350 | {len, bytes} = Protox.Varint.decode(bytes) 3351 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3352 | 3353 | {[function: msg.function ++ [Perftools.Profiles.Function.decode!(delimited)]], 3354 | rest} 3355 | 3356 | {6, _, bytes} -> 3357 | {len, bytes} = Protox.Varint.decode(bytes) 3358 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3359 | {[string_table: msg.string_table ++ [delimited]], rest} 3360 | 3361 | {7, _, bytes} -> 3362 | {value, rest} = Protox.Decode.parse_int64(bytes) 3363 | {[drop_frames: value], rest} 3364 | 3365 | {8, _, bytes} -> 3366 | {value, rest} = Protox.Decode.parse_int64(bytes) 3367 | {[keep_frames: value], rest} 3368 | 3369 | {9, _, bytes} -> 3370 | {value, rest} = Protox.Decode.parse_int64(bytes) 3371 | {[time_nanos: value], rest} 3372 | 3373 | {10, _, bytes} -> 3374 | {value, rest} = Protox.Decode.parse_int64(bytes) 3375 | {[duration_nanos: value], rest} 3376 | 3377 | {11, _, bytes} -> 3378 | {len, bytes} = Protox.Varint.decode(bytes) 3379 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3380 | 3381 | {[ 3382 | period_type: 3383 | Protox.MergeMessage.merge( 3384 | msg.period_type, 3385 | Perftools.Profiles.ValueType.decode!(delimited) 3386 | ) 3387 | ], rest} 3388 | 3389 | {12, _, bytes} -> 3390 | {value, rest} = Protox.Decode.parse_int64(bytes) 3391 | {[period: value], rest} 3392 | 3393 | {13, 2, bytes} -> 3394 | {len, bytes} = Protox.Varint.decode(bytes) 3395 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 3396 | 3397 | {[comment: msg.comment ++ Protox.Decode.parse_repeated_int64([], delimited)], 3398 | rest} 3399 | 3400 | {13, _, bytes} -> 3401 | {value, rest} = Protox.Decode.parse_int64(bytes) 3402 | {[comment: msg.comment ++ [value]], rest} 3403 | 3404 | {14, _, bytes} -> 3405 | {value, rest} = Protox.Decode.parse_int64(bytes) 3406 | {[default_sample_type: value], rest} 3407 | 3408 | {tag, wire_type, rest} -> 3409 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 3410 | 3411 | {[ 3412 | {msg.__struct__.unknown_fields_name, 3413 | [value | msg.__struct__.unknown_fields(msg)]} 3414 | ], rest} 3415 | end 3416 | 3417 | msg_updated = struct(msg, field) 3418 | parse_key_value(rest, msg_updated) 3419 | end 3420 | ) 3421 | 3422 | [] 3423 | ) 3424 | 3425 | ( 3426 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 3427 | def json_decode(input, opts \\ []) do 3428 | try do 3429 | {:ok, json_decode!(input, opts)} 3430 | rescue 3431 | e in Protox.JsonDecodingError -> {:error, e} 3432 | end 3433 | end 3434 | 3435 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 3436 | def json_decode!(input, opts \\ []) do 3437 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 3438 | 3439 | Protox.JsonDecode.decode!( 3440 | input, 3441 | Perftools.Profiles.Profile, 3442 | &json_library_wrapper.decode!(json_library, &1) 3443 | ) 3444 | end 3445 | 3446 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 3447 | def json_encode(msg, opts \\ []) do 3448 | try do 3449 | {:ok, json_encode!(msg, opts)} 3450 | rescue 3451 | e in Protox.JsonEncodingError -> {:error, e} 3452 | end 3453 | end 3454 | 3455 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 3456 | def json_encode!(msg, opts \\ []) do 3457 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 3458 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 3459 | end 3460 | ) 3461 | 3462 | ( 3463 | @deprecated "Use fields_defs()/0 instead" 3464 | @spec defs() :: %{ 3465 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 3466 | } 3467 | def defs() do 3468 | %{ 3469 | 1 => {:sample_type, :unpacked, {:message, Perftools.Profiles.ValueType}}, 3470 | 2 => {:sample, :unpacked, {:message, Perftools.Profiles.Sample}}, 3471 | 3 => {:mapping, :unpacked, {:message, Perftools.Profiles.Mapping}}, 3472 | 4 => {:location, :unpacked, {:message, Perftools.Profiles.Location}}, 3473 | 5 => {:function, :unpacked, {:message, Perftools.Profiles.Function}}, 3474 | 6 => {:string_table, :unpacked, :string}, 3475 | 7 => {:drop_frames, {:scalar, 0}, :int64}, 3476 | 8 => {:keep_frames, {:scalar, 0}, :int64}, 3477 | 9 => {:time_nanos, {:scalar, 0}, :int64}, 3478 | 10 => {:duration_nanos, {:scalar, 0}, :int64}, 3479 | 11 => {:period_type, {:scalar, nil}, {:message, Perftools.Profiles.ValueType}}, 3480 | 12 => {:period, {:scalar, 0}, :int64}, 3481 | 13 => {:comment, :packed, :int64}, 3482 | 14 => {:default_sample_type, {:scalar, 0}, :int64} 3483 | } 3484 | end 3485 | 3486 | @deprecated "Use fields_defs()/0 instead" 3487 | @spec defs_by_name() :: %{ 3488 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 3489 | } 3490 | def defs_by_name() do 3491 | %{ 3492 | comment: {13, :packed, :int64}, 3493 | default_sample_type: {14, {:scalar, 0}, :int64}, 3494 | drop_frames: {7, {:scalar, 0}, :int64}, 3495 | duration_nanos: {10, {:scalar, 0}, :int64}, 3496 | function: {5, :unpacked, {:message, Perftools.Profiles.Function}}, 3497 | keep_frames: {8, {:scalar, 0}, :int64}, 3498 | location: {4, :unpacked, {:message, Perftools.Profiles.Location}}, 3499 | mapping: {3, :unpacked, {:message, Perftools.Profiles.Mapping}}, 3500 | period: {12, {:scalar, 0}, :int64}, 3501 | period_type: {11, {:scalar, nil}, {:message, Perftools.Profiles.ValueType}}, 3502 | sample: {2, :unpacked, {:message, Perftools.Profiles.Sample}}, 3503 | sample_type: {1, :unpacked, {:message, Perftools.Profiles.ValueType}}, 3504 | string_table: {6, :unpacked, :string}, 3505 | time_nanos: {9, {:scalar, 0}, :int64} 3506 | } 3507 | end 3508 | ) 3509 | 3510 | ( 3511 | @spec fields_defs() :: list(Protox.Field.t()) 3512 | def fields_defs() do 3513 | [ 3514 | %{ 3515 | __struct__: Protox.Field, 3516 | json_name: "sampleType", 3517 | kind: :unpacked, 3518 | label: :repeated, 3519 | name: :sample_type, 3520 | tag: 1, 3521 | type: {:message, Perftools.Profiles.ValueType} 3522 | }, 3523 | %{ 3524 | __struct__: Protox.Field, 3525 | json_name: "sample", 3526 | kind: :unpacked, 3527 | label: :repeated, 3528 | name: :sample, 3529 | tag: 2, 3530 | type: {:message, Perftools.Profiles.Sample} 3531 | }, 3532 | %{ 3533 | __struct__: Protox.Field, 3534 | json_name: "mapping", 3535 | kind: :unpacked, 3536 | label: :repeated, 3537 | name: :mapping, 3538 | tag: 3, 3539 | type: {:message, Perftools.Profiles.Mapping} 3540 | }, 3541 | %{ 3542 | __struct__: Protox.Field, 3543 | json_name: "location", 3544 | kind: :unpacked, 3545 | label: :repeated, 3546 | name: :location, 3547 | tag: 4, 3548 | type: {:message, Perftools.Profiles.Location} 3549 | }, 3550 | %{ 3551 | __struct__: Protox.Field, 3552 | json_name: "function", 3553 | kind: :unpacked, 3554 | label: :repeated, 3555 | name: :function, 3556 | tag: 5, 3557 | type: {:message, Perftools.Profiles.Function} 3558 | }, 3559 | %{ 3560 | __struct__: Protox.Field, 3561 | json_name: "stringTable", 3562 | kind: :unpacked, 3563 | label: :repeated, 3564 | name: :string_table, 3565 | tag: 6, 3566 | type: :string 3567 | }, 3568 | %{ 3569 | __struct__: Protox.Field, 3570 | json_name: "dropFrames", 3571 | kind: {:scalar, 0}, 3572 | label: :optional, 3573 | name: :drop_frames, 3574 | tag: 7, 3575 | type: :int64 3576 | }, 3577 | %{ 3578 | __struct__: Protox.Field, 3579 | json_name: "keepFrames", 3580 | kind: {:scalar, 0}, 3581 | label: :optional, 3582 | name: :keep_frames, 3583 | tag: 8, 3584 | type: :int64 3585 | }, 3586 | %{ 3587 | __struct__: Protox.Field, 3588 | json_name: "timeNanos", 3589 | kind: {:scalar, 0}, 3590 | label: :optional, 3591 | name: :time_nanos, 3592 | tag: 9, 3593 | type: :int64 3594 | }, 3595 | %{ 3596 | __struct__: Protox.Field, 3597 | json_name: "durationNanos", 3598 | kind: {:scalar, 0}, 3599 | label: :optional, 3600 | name: :duration_nanos, 3601 | tag: 10, 3602 | type: :int64 3603 | }, 3604 | %{ 3605 | __struct__: Protox.Field, 3606 | json_name: "periodType", 3607 | kind: {:scalar, nil}, 3608 | label: :optional, 3609 | name: :period_type, 3610 | tag: 11, 3611 | type: {:message, Perftools.Profiles.ValueType} 3612 | }, 3613 | %{ 3614 | __struct__: Protox.Field, 3615 | json_name: "period", 3616 | kind: {:scalar, 0}, 3617 | label: :optional, 3618 | name: :period, 3619 | tag: 12, 3620 | type: :int64 3621 | }, 3622 | %{ 3623 | __struct__: Protox.Field, 3624 | json_name: "comment", 3625 | kind: :packed, 3626 | label: :repeated, 3627 | name: :comment, 3628 | tag: 13, 3629 | type: :int64 3630 | }, 3631 | %{ 3632 | __struct__: Protox.Field, 3633 | json_name: "defaultSampleType", 3634 | kind: {:scalar, 0}, 3635 | label: :optional, 3636 | name: :default_sample_type, 3637 | tag: 14, 3638 | type: :int64 3639 | } 3640 | ] 3641 | end 3642 | 3643 | [ 3644 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 3645 | ( 3646 | def field_def(:sample_type) do 3647 | {:ok, 3648 | %{ 3649 | __struct__: Protox.Field, 3650 | json_name: "sampleType", 3651 | kind: :unpacked, 3652 | label: :repeated, 3653 | name: :sample_type, 3654 | tag: 1, 3655 | type: {:message, Perftools.Profiles.ValueType} 3656 | }} 3657 | end 3658 | 3659 | def field_def("sampleType") do 3660 | {:ok, 3661 | %{ 3662 | __struct__: Protox.Field, 3663 | json_name: "sampleType", 3664 | kind: :unpacked, 3665 | label: :repeated, 3666 | name: :sample_type, 3667 | tag: 1, 3668 | type: {:message, Perftools.Profiles.ValueType} 3669 | }} 3670 | end 3671 | 3672 | def field_def("sample_type") do 3673 | {:ok, 3674 | %{ 3675 | __struct__: Protox.Field, 3676 | json_name: "sampleType", 3677 | kind: :unpacked, 3678 | label: :repeated, 3679 | name: :sample_type, 3680 | tag: 1, 3681 | type: {:message, Perftools.Profiles.ValueType} 3682 | }} 3683 | end 3684 | ), 3685 | ( 3686 | def field_def(:sample) do 3687 | {:ok, 3688 | %{ 3689 | __struct__: Protox.Field, 3690 | json_name: "sample", 3691 | kind: :unpacked, 3692 | label: :repeated, 3693 | name: :sample, 3694 | tag: 2, 3695 | type: {:message, Perftools.Profiles.Sample} 3696 | }} 3697 | end 3698 | 3699 | def field_def("sample") do 3700 | {:ok, 3701 | %{ 3702 | __struct__: Protox.Field, 3703 | json_name: "sample", 3704 | kind: :unpacked, 3705 | label: :repeated, 3706 | name: :sample, 3707 | tag: 2, 3708 | type: {:message, Perftools.Profiles.Sample} 3709 | }} 3710 | end 3711 | 3712 | [] 3713 | ), 3714 | ( 3715 | def field_def(:mapping) do 3716 | {:ok, 3717 | %{ 3718 | __struct__: Protox.Field, 3719 | json_name: "mapping", 3720 | kind: :unpacked, 3721 | label: :repeated, 3722 | name: :mapping, 3723 | tag: 3, 3724 | type: {:message, Perftools.Profiles.Mapping} 3725 | }} 3726 | end 3727 | 3728 | def field_def("mapping") do 3729 | {:ok, 3730 | %{ 3731 | __struct__: Protox.Field, 3732 | json_name: "mapping", 3733 | kind: :unpacked, 3734 | label: :repeated, 3735 | name: :mapping, 3736 | tag: 3, 3737 | type: {:message, Perftools.Profiles.Mapping} 3738 | }} 3739 | end 3740 | 3741 | [] 3742 | ), 3743 | ( 3744 | def field_def(:location) do 3745 | {:ok, 3746 | %{ 3747 | __struct__: Protox.Field, 3748 | json_name: "location", 3749 | kind: :unpacked, 3750 | label: :repeated, 3751 | name: :location, 3752 | tag: 4, 3753 | type: {:message, Perftools.Profiles.Location} 3754 | }} 3755 | end 3756 | 3757 | def field_def("location") do 3758 | {:ok, 3759 | %{ 3760 | __struct__: Protox.Field, 3761 | json_name: "location", 3762 | kind: :unpacked, 3763 | label: :repeated, 3764 | name: :location, 3765 | tag: 4, 3766 | type: {:message, Perftools.Profiles.Location} 3767 | }} 3768 | end 3769 | 3770 | [] 3771 | ), 3772 | ( 3773 | def field_def(:function) do 3774 | {:ok, 3775 | %{ 3776 | __struct__: Protox.Field, 3777 | json_name: "function", 3778 | kind: :unpacked, 3779 | label: :repeated, 3780 | name: :function, 3781 | tag: 5, 3782 | type: {:message, Perftools.Profiles.Function} 3783 | }} 3784 | end 3785 | 3786 | def field_def("function") do 3787 | {:ok, 3788 | %{ 3789 | __struct__: Protox.Field, 3790 | json_name: "function", 3791 | kind: :unpacked, 3792 | label: :repeated, 3793 | name: :function, 3794 | tag: 5, 3795 | type: {:message, Perftools.Profiles.Function} 3796 | }} 3797 | end 3798 | 3799 | [] 3800 | ), 3801 | ( 3802 | def field_def(:string_table) do 3803 | {:ok, 3804 | %{ 3805 | __struct__: Protox.Field, 3806 | json_name: "stringTable", 3807 | kind: :unpacked, 3808 | label: :repeated, 3809 | name: :string_table, 3810 | tag: 6, 3811 | type: :string 3812 | }} 3813 | end 3814 | 3815 | def field_def("stringTable") do 3816 | {:ok, 3817 | %{ 3818 | __struct__: Protox.Field, 3819 | json_name: "stringTable", 3820 | kind: :unpacked, 3821 | label: :repeated, 3822 | name: :string_table, 3823 | tag: 6, 3824 | type: :string 3825 | }} 3826 | end 3827 | 3828 | def field_def("string_table") do 3829 | {:ok, 3830 | %{ 3831 | __struct__: Protox.Field, 3832 | json_name: "stringTable", 3833 | kind: :unpacked, 3834 | label: :repeated, 3835 | name: :string_table, 3836 | tag: 6, 3837 | type: :string 3838 | }} 3839 | end 3840 | ), 3841 | ( 3842 | def field_def(:drop_frames) do 3843 | {:ok, 3844 | %{ 3845 | __struct__: Protox.Field, 3846 | json_name: "dropFrames", 3847 | kind: {:scalar, 0}, 3848 | label: :optional, 3849 | name: :drop_frames, 3850 | tag: 7, 3851 | type: :int64 3852 | }} 3853 | end 3854 | 3855 | def field_def("dropFrames") do 3856 | {:ok, 3857 | %{ 3858 | __struct__: Protox.Field, 3859 | json_name: "dropFrames", 3860 | kind: {:scalar, 0}, 3861 | label: :optional, 3862 | name: :drop_frames, 3863 | tag: 7, 3864 | type: :int64 3865 | }} 3866 | end 3867 | 3868 | def field_def("drop_frames") do 3869 | {:ok, 3870 | %{ 3871 | __struct__: Protox.Field, 3872 | json_name: "dropFrames", 3873 | kind: {:scalar, 0}, 3874 | label: :optional, 3875 | name: :drop_frames, 3876 | tag: 7, 3877 | type: :int64 3878 | }} 3879 | end 3880 | ), 3881 | ( 3882 | def field_def(:keep_frames) do 3883 | {:ok, 3884 | %{ 3885 | __struct__: Protox.Field, 3886 | json_name: "keepFrames", 3887 | kind: {:scalar, 0}, 3888 | label: :optional, 3889 | name: :keep_frames, 3890 | tag: 8, 3891 | type: :int64 3892 | }} 3893 | end 3894 | 3895 | def field_def("keepFrames") do 3896 | {:ok, 3897 | %{ 3898 | __struct__: Protox.Field, 3899 | json_name: "keepFrames", 3900 | kind: {:scalar, 0}, 3901 | label: :optional, 3902 | name: :keep_frames, 3903 | tag: 8, 3904 | type: :int64 3905 | }} 3906 | end 3907 | 3908 | def field_def("keep_frames") do 3909 | {:ok, 3910 | %{ 3911 | __struct__: Protox.Field, 3912 | json_name: "keepFrames", 3913 | kind: {:scalar, 0}, 3914 | label: :optional, 3915 | name: :keep_frames, 3916 | tag: 8, 3917 | type: :int64 3918 | }} 3919 | end 3920 | ), 3921 | ( 3922 | def field_def(:time_nanos) do 3923 | {:ok, 3924 | %{ 3925 | __struct__: Protox.Field, 3926 | json_name: "timeNanos", 3927 | kind: {:scalar, 0}, 3928 | label: :optional, 3929 | name: :time_nanos, 3930 | tag: 9, 3931 | type: :int64 3932 | }} 3933 | end 3934 | 3935 | def field_def("timeNanos") do 3936 | {:ok, 3937 | %{ 3938 | __struct__: Protox.Field, 3939 | json_name: "timeNanos", 3940 | kind: {:scalar, 0}, 3941 | label: :optional, 3942 | name: :time_nanos, 3943 | tag: 9, 3944 | type: :int64 3945 | }} 3946 | end 3947 | 3948 | def field_def("time_nanos") do 3949 | {:ok, 3950 | %{ 3951 | __struct__: Protox.Field, 3952 | json_name: "timeNanos", 3953 | kind: {:scalar, 0}, 3954 | label: :optional, 3955 | name: :time_nanos, 3956 | tag: 9, 3957 | type: :int64 3958 | }} 3959 | end 3960 | ), 3961 | ( 3962 | def field_def(:duration_nanos) do 3963 | {:ok, 3964 | %{ 3965 | __struct__: Protox.Field, 3966 | json_name: "durationNanos", 3967 | kind: {:scalar, 0}, 3968 | label: :optional, 3969 | name: :duration_nanos, 3970 | tag: 10, 3971 | type: :int64 3972 | }} 3973 | end 3974 | 3975 | def field_def("durationNanos") do 3976 | {:ok, 3977 | %{ 3978 | __struct__: Protox.Field, 3979 | json_name: "durationNanos", 3980 | kind: {:scalar, 0}, 3981 | label: :optional, 3982 | name: :duration_nanos, 3983 | tag: 10, 3984 | type: :int64 3985 | }} 3986 | end 3987 | 3988 | def field_def("duration_nanos") do 3989 | {:ok, 3990 | %{ 3991 | __struct__: Protox.Field, 3992 | json_name: "durationNanos", 3993 | kind: {:scalar, 0}, 3994 | label: :optional, 3995 | name: :duration_nanos, 3996 | tag: 10, 3997 | type: :int64 3998 | }} 3999 | end 4000 | ), 4001 | ( 4002 | def field_def(:period_type) do 4003 | {:ok, 4004 | %{ 4005 | __struct__: Protox.Field, 4006 | json_name: "periodType", 4007 | kind: {:scalar, nil}, 4008 | label: :optional, 4009 | name: :period_type, 4010 | tag: 11, 4011 | type: {:message, Perftools.Profiles.ValueType} 4012 | }} 4013 | end 4014 | 4015 | def field_def("periodType") do 4016 | {:ok, 4017 | %{ 4018 | __struct__: Protox.Field, 4019 | json_name: "periodType", 4020 | kind: {:scalar, nil}, 4021 | label: :optional, 4022 | name: :period_type, 4023 | tag: 11, 4024 | type: {:message, Perftools.Profiles.ValueType} 4025 | }} 4026 | end 4027 | 4028 | def field_def("period_type") do 4029 | {:ok, 4030 | %{ 4031 | __struct__: Protox.Field, 4032 | json_name: "periodType", 4033 | kind: {:scalar, nil}, 4034 | label: :optional, 4035 | name: :period_type, 4036 | tag: 11, 4037 | type: {:message, Perftools.Profiles.ValueType} 4038 | }} 4039 | end 4040 | ), 4041 | ( 4042 | def field_def(:period) do 4043 | {:ok, 4044 | %{ 4045 | __struct__: Protox.Field, 4046 | json_name: "period", 4047 | kind: {:scalar, 0}, 4048 | label: :optional, 4049 | name: :period, 4050 | tag: 12, 4051 | type: :int64 4052 | }} 4053 | end 4054 | 4055 | def field_def("period") do 4056 | {:ok, 4057 | %{ 4058 | __struct__: Protox.Field, 4059 | json_name: "period", 4060 | kind: {:scalar, 0}, 4061 | label: :optional, 4062 | name: :period, 4063 | tag: 12, 4064 | type: :int64 4065 | }} 4066 | end 4067 | 4068 | [] 4069 | ), 4070 | ( 4071 | def field_def(:comment) do 4072 | {:ok, 4073 | %{ 4074 | __struct__: Protox.Field, 4075 | json_name: "comment", 4076 | kind: :packed, 4077 | label: :repeated, 4078 | name: :comment, 4079 | tag: 13, 4080 | type: :int64 4081 | }} 4082 | end 4083 | 4084 | def field_def("comment") do 4085 | {:ok, 4086 | %{ 4087 | __struct__: Protox.Field, 4088 | json_name: "comment", 4089 | kind: :packed, 4090 | label: :repeated, 4091 | name: :comment, 4092 | tag: 13, 4093 | type: :int64 4094 | }} 4095 | end 4096 | 4097 | [] 4098 | ), 4099 | ( 4100 | def field_def(:default_sample_type) do 4101 | {:ok, 4102 | %{ 4103 | __struct__: Protox.Field, 4104 | json_name: "defaultSampleType", 4105 | kind: {:scalar, 0}, 4106 | label: :optional, 4107 | name: :default_sample_type, 4108 | tag: 14, 4109 | type: :int64 4110 | }} 4111 | end 4112 | 4113 | def field_def("defaultSampleType") do 4114 | {:ok, 4115 | %{ 4116 | __struct__: Protox.Field, 4117 | json_name: "defaultSampleType", 4118 | kind: {:scalar, 0}, 4119 | label: :optional, 4120 | name: :default_sample_type, 4121 | tag: 14, 4122 | type: :int64 4123 | }} 4124 | end 4125 | 4126 | def field_def("default_sample_type") do 4127 | {:ok, 4128 | %{ 4129 | __struct__: Protox.Field, 4130 | json_name: "defaultSampleType", 4131 | kind: {:scalar, 0}, 4132 | label: :optional, 4133 | name: :default_sample_type, 4134 | tag: 14, 4135 | type: :int64 4136 | }} 4137 | end 4138 | ), 4139 | def field_def(_) do 4140 | {:error, :no_such_field} 4141 | end 4142 | ] 4143 | ) 4144 | 4145 | ( 4146 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 4147 | def unknown_fields(msg) do 4148 | msg.__uf__ 4149 | end 4150 | 4151 | @spec unknown_fields_name() :: :__uf__ 4152 | def unknown_fields_name() do 4153 | :__uf__ 4154 | end 4155 | 4156 | @spec clear_unknown_fields(struct) :: struct 4157 | def clear_unknown_fields(msg) do 4158 | struct!(msg, [{unknown_fields_name(), []}]) 4159 | end 4160 | ) 4161 | 4162 | ( 4163 | @spec required_fields() :: [] 4164 | def required_fields() do 4165 | [] 4166 | end 4167 | ) 4168 | 4169 | ( 4170 | @spec syntax() :: atom() 4171 | def syntax() do 4172 | :proto3 4173 | end 4174 | ) 4175 | 4176 | [ 4177 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 4178 | def default(:sample_type) do 4179 | {:error, :no_default_value} 4180 | end, 4181 | def default(:sample) do 4182 | {:error, :no_default_value} 4183 | end, 4184 | def default(:mapping) do 4185 | {:error, :no_default_value} 4186 | end, 4187 | def default(:location) do 4188 | {:error, :no_default_value} 4189 | end, 4190 | def default(:function) do 4191 | {:error, :no_default_value} 4192 | end, 4193 | def default(:string_table) do 4194 | {:error, :no_default_value} 4195 | end, 4196 | def default(:drop_frames) do 4197 | {:ok, 0} 4198 | end, 4199 | def default(:keep_frames) do 4200 | {:ok, 0} 4201 | end, 4202 | def default(:time_nanos) do 4203 | {:ok, 0} 4204 | end, 4205 | def default(:duration_nanos) do 4206 | {:ok, 0} 4207 | end, 4208 | def default(:period_type) do 4209 | {:ok, nil} 4210 | end, 4211 | def default(:period) do 4212 | {:ok, 0} 4213 | end, 4214 | def default(:comment) do 4215 | {:error, :no_default_value} 4216 | end, 4217 | def default(:default_sample_type) do 4218 | {:ok, 0} 4219 | end, 4220 | def default(_) do 4221 | {:error, :no_such_field} 4222 | end 4223 | ] 4224 | 4225 | ( 4226 | @spec file_options() :: struct() 4227 | def file_options() do 4228 | file_options = %{ 4229 | __struct__: Protox.Google.Protobuf.FileOptions, 4230 | __uf__: [], 4231 | cc_enable_arenas: nil, 4232 | cc_generic_services: nil, 4233 | csharp_namespace: nil, 4234 | deprecated: nil, 4235 | go_package: nil, 4236 | java_generate_equals_and_hash: nil, 4237 | java_generic_services: nil, 4238 | java_multiple_files: nil, 4239 | java_outer_classname: "ProfileProto", 4240 | java_package: "com.google.perftools.profiles", 4241 | java_string_check_utf8: nil, 4242 | objc_class_prefix: nil, 4243 | optimize_for: nil, 4244 | php_class_prefix: nil, 4245 | php_generic_services: nil, 4246 | php_metadata_namespace: nil, 4247 | php_namespace: nil, 4248 | py_generic_services: nil, 4249 | ruby_package: nil, 4250 | swift_prefix: nil, 4251 | uninterpreted_option: [] 4252 | } 4253 | 4254 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 4255 | true -> 4256 | bytes = 4257 | file_options 4258 | |> Protox.Google.Protobuf.FileOptions.encode!() 4259 | |> :binary.list_to_bin() 4260 | 4261 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 4262 | 4263 | false -> 4264 | file_options 4265 | end 4266 | end 4267 | ) 4268 | end, 4269 | defmodule Perftools.Profiles.Sample do 4270 | @moduledoc false 4271 | defstruct location_id: [], value: [], label: [], __uf__: [] 4272 | 4273 | ( 4274 | ( 4275 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 4276 | def encode(msg) do 4277 | try do 4278 | {:ok, encode!(msg)} 4279 | rescue 4280 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 4281 | end 4282 | end 4283 | 4284 | @spec encode!(struct) :: iodata | no_return 4285 | def encode!(msg) do 4286 | [] 4287 | |> encode_location_id(msg) 4288 | |> encode_value(msg) 4289 | |> encode_label(msg) 4290 | |> encode_unknown_fields(msg) 4291 | end 4292 | ) 4293 | 4294 | [] 4295 | 4296 | [ 4297 | defp encode_location_id(acc, msg) do 4298 | try do 4299 | case msg.location_id do 4300 | [] -> 4301 | acc 4302 | 4303 | values -> 4304 | [ 4305 | acc, 4306 | "\n", 4307 | ( 4308 | {bytes, len} = 4309 | Enum.reduce(values, {[], 0}, fn value, {acc, len} -> 4310 | value_bytes = :binary.list_to_bin([Protox.Encode.encode_uint64(value)]) 4311 | {[acc, value_bytes], len + byte_size(value_bytes)} 4312 | end) 4313 | 4314 | [Protox.Varint.encode(len), bytes] 4315 | ) 4316 | ] 4317 | end 4318 | rescue 4319 | ArgumentError -> 4320 | reraise Protox.EncodingError.new(:location_id, "invalid field value"), 4321 | __STACKTRACE__ 4322 | end 4323 | end, 4324 | defp encode_value(acc, msg) do 4325 | try do 4326 | case msg.value do 4327 | [] -> 4328 | acc 4329 | 4330 | values -> 4331 | [ 4332 | acc, 4333 | "\x12", 4334 | ( 4335 | {bytes, len} = 4336 | Enum.reduce(values, {[], 0}, fn value, {acc, len} -> 4337 | value_bytes = :binary.list_to_bin([Protox.Encode.encode_int64(value)]) 4338 | {[acc, value_bytes], len + byte_size(value_bytes)} 4339 | end) 4340 | 4341 | [Protox.Varint.encode(len), bytes] 4342 | ) 4343 | ] 4344 | end 4345 | rescue 4346 | ArgumentError -> 4347 | reraise Protox.EncodingError.new(:value, "invalid field value"), __STACKTRACE__ 4348 | end 4349 | end, 4350 | defp encode_label(acc, msg) do 4351 | try do 4352 | case msg.label do 4353 | [] -> 4354 | acc 4355 | 4356 | values -> 4357 | [ 4358 | acc, 4359 | Enum.reduce(values, [], fn value, acc -> 4360 | [acc, "\x1A", Protox.Encode.encode_message(value)] 4361 | end) 4362 | ] 4363 | end 4364 | rescue 4365 | ArgumentError -> 4366 | reraise Protox.EncodingError.new(:label, "invalid field value"), __STACKTRACE__ 4367 | end 4368 | end 4369 | ] 4370 | 4371 | defp encode_unknown_fields(acc, msg) do 4372 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 4373 | case wire_type do 4374 | 0 -> 4375 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 4376 | 4377 | 1 -> 4378 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 4379 | 4380 | 2 -> 4381 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 4382 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 4383 | 4384 | 5 -> 4385 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 4386 | end 4387 | end) 4388 | end 4389 | ) 4390 | 4391 | ( 4392 | ( 4393 | @spec decode(binary) :: {:ok, struct} | {:error, any} 4394 | def decode(bytes) do 4395 | try do 4396 | {:ok, decode!(bytes)} 4397 | rescue 4398 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 4399 | {:error, e} 4400 | end 4401 | end 4402 | 4403 | ( 4404 | @spec decode!(binary) :: struct | no_return 4405 | def decode!(bytes) do 4406 | parse_key_value(bytes, struct(Perftools.Profiles.Sample)) 4407 | end 4408 | ) 4409 | ) 4410 | 4411 | ( 4412 | @spec parse_key_value(binary, struct) :: struct 4413 | defp parse_key_value(<<>>, msg) do 4414 | msg 4415 | end 4416 | 4417 | defp parse_key_value(bytes, msg) do 4418 | {field, rest} = 4419 | case Protox.Decode.parse_key(bytes) do 4420 | {0, _, _} -> 4421 | raise %Protox.IllegalTagError{} 4422 | 4423 | {1, 2, bytes} -> 4424 | {len, bytes} = Protox.Varint.decode(bytes) 4425 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 4426 | 4427 | {[ 4428 | location_id: 4429 | msg.location_id ++ Protox.Decode.parse_repeated_uint64([], delimited) 4430 | ], rest} 4431 | 4432 | {1, _, bytes} -> 4433 | {value, rest} = Protox.Decode.parse_uint64(bytes) 4434 | {[location_id: msg.location_id ++ [value]], rest} 4435 | 4436 | {2, 2, bytes} -> 4437 | {len, bytes} = Protox.Varint.decode(bytes) 4438 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 4439 | {[value: msg.value ++ Protox.Decode.parse_repeated_int64([], delimited)], rest} 4440 | 4441 | {2, _, bytes} -> 4442 | {value, rest} = Protox.Decode.parse_int64(bytes) 4443 | {[value: msg.value ++ [value]], rest} 4444 | 4445 | {3, _, bytes} -> 4446 | {len, bytes} = Protox.Varint.decode(bytes) 4447 | {delimited, rest} = Protox.Decode.parse_delimited(bytes, len) 4448 | {[label: msg.label ++ [Perftools.Profiles.Label.decode!(delimited)]], rest} 4449 | 4450 | {tag, wire_type, rest} -> 4451 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 4452 | 4453 | {[ 4454 | {msg.__struct__.unknown_fields_name, 4455 | [value | msg.__struct__.unknown_fields(msg)]} 4456 | ], rest} 4457 | end 4458 | 4459 | msg_updated = struct(msg, field) 4460 | parse_key_value(rest, msg_updated) 4461 | end 4462 | ) 4463 | 4464 | [] 4465 | ) 4466 | 4467 | ( 4468 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 4469 | def json_decode(input, opts \\ []) do 4470 | try do 4471 | {:ok, json_decode!(input, opts)} 4472 | rescue 4473 | e in Protox.JsonDecodingError -> {:error, e} 4474 | end 4475 | end 4476 | 4477 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 4478 | def json_decode!(input, opts \\ []) do 4479 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 4480 | 4481 | Protox.JsonDecode.decode!( 4482 | input, 4483 | Perftools.Profiles.Sample, 4484 | &json_library_wrapper.decode!(json_library, &1) 4485 | ) 4486 | end 4487 | 4488 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 4489 | def json_encode(msg, opts \\ []) do 4490 | try do 4491 | {:ok, json_encode!(msg, opts)} 4492 | rescue 4493 | e in Protox.JsonEncodingError -> {:error, e} 4494 | end 4495 | end 4496 | 4497 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 4498 | def json_encode!(msg, opts \\ []) do 4499 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 4500 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 4501 | end 4502 | ) 4503 | 4504 | ( 4505 | @deprecated "Use fields_defs()/0 instead" 4506 | @spec defs() :: %{ 4507 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 4508 | } 4509 | def defs() do 4510 | %{ 4511 | 1 => {:location_id, :packed, :uint64}, 4512 | 2 => {:value, :packed, :int64}, 4513 | 3 => {:label, :unpacked, {:message, Perftools.Profiles.Label}} 4514 | } 4515 | end 4516 | 4517 | @deprecated "Use fields_defs()/0 instead" 4518 | @spec defs_by_name() :: %{ 4519 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 4520 | } 4521 | def defs_by_name() do 4522 | %{ 4523 | label: {3, :unpacked, {:message, Perftools.Profiles.Label}}, 4524 | location_id: {1, :packed, :uint64}, 4525 | value: {2, :packed, :int64} 4526 | } 4527 | end 4528 | ) 4529 | 4530 | ( 4531 | @spec fields_defs() :: list(Protox.Field.t()) 4532 | def fields_defs() do 4533 | [ 4534 | %{ 4535 | __struct__: Protox.Field, 4536 | json_name: "locationId", 4537 | kind: :packed, 4538 | label: :repeated, 4539 | name: :location_id, 4540 | tag: 1, 4541 | type: :uint64 4542 | }, 4543 | %{ 4544 | __struct__: Protox.Field, 4545 | json_name: "value", 4546 | kind: :packed, 4547 | label: :repeated, 4548 | name: :value, 4549 | tag: 2, 4550 | type: :int64 4551 | }, 4552 | %{ 4553 | __struct__: Protox.Field, 4554 | json_name: "label", 4555 | kind: :unpacked, 4556 | label: :repeated, 4557 | name: :label, 4558 | tag: 3, 4559 | type: {:message, Perftools.Profiles.Label} 4560 | } 4561 | ] 4562 | end 4563 | 4564 | [ 4565 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 4566 | ( 4567 | def field_def(:location_id) do 4568 | {:ok, 4569 | %{ 4570 | __struct__: Protox.Field, 4571 | json_name: "locationId", 4572 | kind: :packed, 4573 | label: :repeated, 4574 | name: :location_id, 4575 | tag: 1, 4576 | type: :uint64 4577 | }} 4578 | end 4579 | 4580 | def field_def("locationId") do 4581 | {:ok, 4582 | %{ 4583 | __struct__: Protox.Field, 4584 | json_name: "locationId", 4585 | kind: :packed, 4586 | label: :repeated, 4587 | name: :location_id, 4588 | tag: 1, 4589 | type: :uint64 4590 | }} 4591 | end 4592 | 4593 | def field_def("location_id") do 4594 | {:ok, 4595 | %{ 4596 | __struct__: Protox.Field, 4597 | json_name: "locationId", 4598 | kind: :packed, 4599 | label: :repeated, 4600 | name: :location_id, 4601 | tag: 1, 4602 | type: :uint64 4603 | }} 4604 | end 4605 | ), 4606 | ( 4607 | def field_def(:value) do 4608 | {:ok, 4609 | %{ 4610 | __struct__: Protox.Field, 4611 | json_name: "value", 4612 | kind: :packed, 4613 | label: :repeated, 4614 | name: :value, 4615 | tag: 2, 4616 | type: :int64 4617 | }} 4618 | end 4619 | 4620 | def field_def("value") do 4621 | {:ok, 4622 | %{ 4623 | __struct__: Protox.Field, 4624 | json_name: "value", 4625 | kind: :packed, 4626 | label: :repeated, 4627 | name: :value, 4628 | tag: 2, 4629 | type: :int64 4630 | }} 4631 | end 4632 | 4633 | [] 4634 | ), 4635 | ( 4636 | def field_def(:label) do 4637 | {:ok, 4638 | %{ 4639 | __struct__: Protox.Field, 4640 | json_name: "label", 4641 | kind: :unpacked, 4642 | label: :repeated, 4643 | name: :label, 4644 | tag: 3, 4645 | type: {:message, Perftools.Profiles.Label} 4646 | }} 4647 | end 4648 | 4649 | def field_def("label") do 4650 | {:ok, 4651 | %{ 4652 | __struct__: Protox.Field, 4653 | json_name: "label", 4654 | kind: :unpacked, 4655 | label: :repeated, 4656 | name: :label, 4657 | tag: 3, 4658 | type: {:message, Perftools.Profiles.Label} 4659 | }} 4660 | end 4661 | 4662 | [] 4663 | ), 4664 | def field_def(_) do 4665 | {:error, :no_such_field} 4666 | end 4667 | ] 4668 | ) 4669 | 4670 | ( 4671 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 4672 | def unknown_fields(msg) do 4673 | msg.__uf__ 4674 | end 4675 | 4676 | @spec unknown_fields_name() :: :__uf__ 4677 | def unknown_fields_name() do 4678 | :__uf__ 4679 | end 4680 | 4681 | @spec clear_unknown_fields(struct) :: struct 4682 | def clear_unknown_fields(msg) do 4683 | struct!(msg, [{unknown_fields_name(), []}]) 4684 | end 4685 | ) 4686 | 4687 | ( 4688 | @spec required_fields() :: [] 4689 | def required_fields() do 4690 | [] 4691 | end 4692 | ) 4693 | 4694 | ( 4695 | @spec syntax() :: atom() 4696 | def syntax() do 4697 | :proto3 4698 | end 4699 | ) 4700 | 4701 | [ 4702 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 4703 | def default(:location_id) do 4704 | {:error, :no_default_value} 4705 | end, 4706 | def default(:value) do 4707 | {:error, :no_default_value} 4708 | end, 4709 | def default(:label) do 4710 | {:error, :no_default_value} 4711 | end, 4712 | def default(_) do 4713 | {:error, :no_such_field} 4714 | end 4715 | ] 4716 | 4717 | ( 4718 | @spec file_options() :: struct() 4719 | def file_options() do 4720 | file_options = %{ 4721 | __struct__: Protox.Google.Protobuf.FileOptions, 4722 | __uf__: [], 4723 | cc_enable_arenas: nil, 4724 | cc_generic_services: nil, 4725 | csharp_namespace: nil, 4726 | deprecated: nil, 4727 | go_package: nil, 4728 | java_generate_equals_and_hash: nil, 4729 | java_generic_services: nil, 4730 | java_multiple_files: nil, 4731 | java_outer_classname: "ProfileProto", 4732 | java_package: "com.google.perftools.profiles", 4733 | java_string_check_utf8: nil, 4734 | objc_class_prefix: nil, 4735 | optimize_for: nil, 4736 | php_class_prefix: nil, 4737 | php_generic_services: nil, 4738 | php_metadata_namespace: nil, 4739 | php_namespace: nil, 4740 | py_generic_services: nil, 4741 | ruby_package: nil, 4742 | swift_prefix: nil, 4743 | uninterpreted_option: [] 4744 | } 4745 | 4746 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 4747 | true -> 4748 | bytes = 4749 | file_options 4750 | |> Protox.Google.Protobuf.FileOptions.encode!() 4751 | |> :binary.list_to_bin() 4752 | 4753 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 4754 | 4755 | false -> 4756 | file_options 4757 | end 4758 | end 4759 | ) 4760 | end, 4761 | defmodule Perftools.Profiles.ValueType do 4762 | @moduledoc false 4763 | defstruct type: 0, unit: 0, __uf__: [] 4764 | 4765 | ( 4766 | ( 4767 | @spec encode(struct) :: {:ok, iodata} | {:error, any} 4768 | def encode(msg) do 4769 | try do 4770 | {:ok, encode!(msg)} 4771 | rescue 4772 | e in [Protox.EncodingError, Protox.RequiredFieldsError] -> {:error, e} 4773 | end 4774 | end 4775 | 4776 | @spec encode!(struct) :: iodata | no_return 4777 | def encode!(msg) do 4778 | [] |> encode_type(msg) |> encode_unit(msg) |> encode_unknown_fields(msg) 4779 | end 4780 | ) 4781 | 4782 | [] 4783 | 4784 | [ 4785 | defp encode_type(acc, msg) do 4786 | try do 4787 | if msg.type == 0 do 4788 | acc 4789 | else 4790 | [acc, "\b", Protox.Encode.encode_int64(msg.type)] 4791 | end 4792 | rescue 4793 | ArgumentError -> 4794 | reraise Protox.EncodingError.new(:type, "invalid field value"), __STACKTRACE__ 4795 | end 4796 | end, 4797 | defp encode_unit(acc, msg) do 4798 | try do 4799 | if msg.unit == 0 do 4800 | acc 4801 | else 4802 | [acc, "\x10", Protox.Encode.encode_int64(msg.unit)] 4803 | end 4804 | rescue 4805 | ArgumentError -> 4806 | reraise Protox.EncodingError.new(:unit, "invalid field value"), __STACKTRACE__ 4807 | end 4808 | end 4809 | ] 4810 | 4811 | defp encode_unknown_fields(acc, msg) do 4812 | Enum.reduce(msg.__struct__.unknown_fields(msg), acc, fn {tag, wire_type, bytes}, acc -> 4813 | case wire_type do 4814 | 0 -> 4815 | [acc, Protox.Encode.make_key_bytes(tag, :int32), bytes] 4816 | 4817 | 1 -> 4818 | [acc, Protox.Encode.make_key_bytes(tag, :double), bytes] 4819 | 4820 | 2 -> 4821 | len_bytes = bytes |> byte_size() |> Protox.Varint.encode() 4822 | [acc, Protox.Encode.make_key_bytes(tag, :packed), len_bytes, bytes] 4823 | 4824 | 5 -> 4825 | [acc, Protox.Encode.make_key_bytes(tag, :float), bytes] 4826 | end 4827 | end) 4828 | end 4829 | ) 4830 | 4831 | ( 4832 | ( 4833 | @spec decode(binary) :: {:ok, struct} | {:error, any} 4834 | def decode(bytes) do 4835 | try do 4836 | {:ok, decode!(bytes)} 4837 | rescue 4838 | e in [Protox.DecodingError, Protox.IllegalTagError, Protox.RequiredFieldsError] -> 4839 | {:error, e} 4840 | end 4841 | end 4842 | 4843 | ( 4844 | @spec decode!(binary) :: struct | no_return 4845 | def decode!(bytes) do 4846 | parse_key_value(bytes, struct(Perftools.Profiles.ValueType)) 4847 | end 4848 | ) 4849 | ) 4850 | 4851 | ( 4852 | @spec parse_key_value(binary, struct) :: struct 4853 | defp parse_key_value(<<>>, msg) do 4854 | msg 4855 | end 4856 | 4857 | defp parse_key_value(bytes, msg) do 4858 | {field, rest} = 4859 | case Protox.Decode.parse_key(bytes) do 4860 | {0, _, _} -> 4861 | raise %Protox.IllegalTagError{} 4862 | 4863 | {1, _, bytes} -> 4864 | {value, rest} = Protox.Decode.parse_int64(bytes) 4865 | {[type: value], rest} 4866 | 4867 | {2, _, bytes} -> 4868 | {value, rest} = Protox.Decode.parse_int64(bytes) 4869 | {[unit: value], rest} 4870 | 4871 | {tag, wire_type, rest} -> 4872 | {value, rest} = Protox.Decode.parse_unknown(tag, wire_type, rest) 4873 | 4874 | {[ 4875 | {msg.__struct__.unknown_fields_name, 4876 | [value | msg.__struct__.unknown_fields(msg)]} 4877 | ], rest} 4878 | end 4879 | 4880 | msg_updated = struct(msg, field) 4881 | parse_key_value(rest, msg_updated) 4882 | end 4883 | ) 4884 | 4885 | [] 4886 | ) 4887 | 4888 | ( 4889 | @spec json_decode(iodata(), keyword()) :: {:ok, struct()} | {:error, any()} 4890 | def json_decode(input, opts \\ []) do 4891 | try do 4892 | {:ok, json_decode!(input, opts)} 4893 | rescue 4894 | e in Protox.JsonDecodingError -> {:error, e} 4895 | end 4896 | end 4897 | 4898 | @spec json_decode!(iodata(), keyword()) :: struct() | no_return() 4899 | def json_decode!(input, opts \\ []) do 4900 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :decode) 4901 | 4902 | Protox.JsonDecode.decode!( 4903 | input, 4904 | Perftools.Profiles.ValueType, 4905 | &json_library_wrapper.decode!(json_library, &1) 4906 | ) 4907 | end 4908 | 4909 | @spec json_encode(struct(), keyword()) :: {:ok, iodata()} | {:error, any()} 4910 | def json_encode(msg, opts \\ []) do 4911 | try do 4912 | {:ok, json_encode!(msg, opts)} 4913 | rescue 4914 | e in Protox.JsonEncodingError -> {:error, e} 4915 | end 4916 | end 4917 | 4918 | @spec json_encode!(struct(), keyword()) :: iodata() | no_return() 4919 | def json_encode!(msg, opts \\ []) do 4920 | {json_library_wrapper, json_library} = Protox.JsonLibrary.get_library(opts, :encode) 4921 | Protox.JsonEncode.encode!(msg, &json_library_wrapper.encode!(json_library, &1)) 4922 | end 4923 | ) 4924 | 4925 | ( 4926 | @deprecated "Use fields_defs()/0 instead" 4927 | @spec defs() :: %{ 4928 | required(non_neg_integer) => {atom, Protox.Types.kind(), Protox.Types.type()} 4929 | } 4930 | def defs() do 4931 | %{1 => {:type, {:scalar, 0}, :int64}, 2 => {:unit, {:scalar, 0}, :int64}} 4932 | end 4933 | 4934 | @deprecated "Use fields_defs()/0 instead" 4935 | @spec defs_by_name() :: %{ 4936 | required(atom) => {non_neg_integer, Protox.Types.kind(), Protox.Types.type()} 4937 | } 4938 | def defs_by_name() do 4939 | %{type: {1, {:scalar, 0}, :int64}, unit: {2, {:scalar, 0}, :int64}} 4940 | end 4941 | ) 4942 | 4943 | ( 4944 | @spec fields_defs() :: list(Protox.Field.t()) 4945 | def fields_defs() do 4946 | [ 4947 | %{ 4948 | __struct__: Protox.Field, 4949 | json_name: "type", 4950 | kind: {:scalar, 0}, 4951 | label: :optional, 4952 | name: :type, 4953 | tag: 1, 4954 | type: :int64 4955 | }, 4956 | %{ 4957 | __struct__: Protox.Field, 4958 | json_name: "unit", 4959 | kind: {:scalar, 0}, 4960 | label: :optional, 4961 | name: :unit, 4962 | tag: 2, 4963 | type: :int64 4964 | } 4965 | ] 4966 | end 4967 | 4968 | [ 4969 | @spec(field_def(atom) :: {:ok, Protox.Field.t()} | {:error, :no_such_field}), 4970 | ( 4971 | def field_def(:type) do 4972 | {:ok, 4973 | %{ 4974 | __struct__: Protox.Field, 4975 | json_name: "type", 4976 | kind: {:scalar, 0}, 4977 | label: :optional, 4978 | name: :type, 4979 | tag: 1, 4980 | type: :int64 4981 | }} 4982 | end 4983 | 4984 | def field_def("type") do 4985 | {:ok, 4986 | %{ 4987 | __struct__: Protox.Field, 4988 | json_name: "type", 4989 | kind: {:scalar, 0}, 4990 | label: :optional, 4991 | name: :type, 4992 | tag: 1, 4993 | type: :int64 4994 | }} 4995 | end 4996 | 4997 | [] 4998 | ), 4999 | ( 5000 | def field_def(:unit) do 5001 | {:ok, 5002 | %{ 5003 | __struct__: Protox.Field, 5004 | json_name: "unit", 5005 | kind: {:scalar, 0}, 5006 | label: :optional, 5007 | name: :unit, 5008 | tag: 2, 5009 | type: :int64 5010 | }} 5011 | end 5012 | 5013 | def field_def("unit") do 5014 | {:ok, 5015 | %{ 5016 | __struct__: Protox.Field, 5017 | json_name: "unit", 5018 | kind: {:scalar, 0}, 5019 | label: :optional, 5020 | name: :unit, 5021 | tag: 2, 5022 | type: :int64 5023 | }} 5024 | end 5025 | 5026 | [] 5027 | ), 5028 | def field_def(_) do 5029 | {:error, :no_such_field} 5030 | end 5031 | ] 5032 | ) 5033 | 5034 | ( 5035 | @spec unknown_fields(struct) :: [{non_neg_integer, Protox.Types.tag(), binary}] 5036 | def unknown_fields(msg) do 5037 | msg.__uf__ 5038 | end 5039 | 5040 | @spec unknown_fields_name() :: :__uf__ 5041 | def unknown_fields_name() do 5042 | :__uf__ 5043 | end 5044 | 5045 | @spec clear_unknown_fields(struct) :: struct 5046 | def clear_unknown_fields(msg) do 5047 | struct!(msg, [{unknown_fields_name(), []}]) 5048 | end 5049 | ) 5050 | 5051 | ( 5052 | @spec required_fields() :: [] 5053 | def required_fields() do 5054 | [] 5055 | end 5056 | ) 5057 | 5058 | ( 5059 | @spec syntax() :: atom() 5060 | def syntax() do 5061 | :proto3 5062 | end 5063 | ) 5064 | 5065 | [ 5066 | @spec(default(atom) :: {:ok, boolean | integer | String.t() | float} | {:error, atom}), 5067 | def default(:type) do 5068 | {:ok, 0} 5069 | end, 5070 | def default(:unit) do 5071 | {:ok, 0} 5072 | end, 5073 | def default(_) do 5074 | {:error, :no_such_field} 5075 | end 5076 | ] 5077 | 5078 | ( 5079 | @spec file_options() :: struct() 5080 | def file_options() do 5081 | file_options = %{ 5082 | __struct__: Protox.Google.Protobuf.FileOptions, 5083 | __uf__: [], 5084 | cc_enable_arenas: nil, 5085 | cc_generic_services: nil, 5086 | csharp_namespace: nil, 5087 | deprecated: nil, 5088 | go_package: nil, 5089 | java_generate_equals_and_hash: nil, 5090 | java_generic_services: nil, 5091 | java_multiple_files: nil, 5092 | java_outer_classname: "ProfileProto", 5093 | java_package: "com.google.perftools.profiles", 5094 | java_string_check_utf8: nil, 5095 | objc_class_prefix: nil, 5096 | optimize_for: nil, 5097 | php_class_prefix: nil, 5098 | php_generic_services: nil, 5099 | php_metadata_namespace: nil, 5100 | php_namespace: nil, 5101 | py_generic_services: nil, 5102 | ruby_package: nil, 5103 | swift_prefix: nil, 5104 | uninterpreted_option: [] 5105 | } 5106 | 5107 | case function_exported?(Google.Protobuf.FileOptions, :decode!, 1) do 5108 | true -> 5109 | bytes = 5110 | file_options 5111 | |> Protox.Google.Protobuf.FileOptions.encode!() 5112 | |> :binary.list_to_bin() 5113 | 5114 | apply(Google.Protobuf.FileOptions, :decode!, [bytes]) 5115 | 5116 | false -> 5117 | file_options 5118 | end 5119 | end 5120 | ) 5121 | end 5122 | ] 5123 | --------------------------------------------------------------------------------