Create a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compileCreate a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compile

Interview Assignment

Overview

You assignment is to create a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compiler. In this exercise, we expect you to use v3.13.0, so please install it from the the releases.

We expect this assignment to take between 2-3 hours to complete. A significant portion of this assignment is to test your ability to research and learn how to interact with a foreign tool. The implementation itself is not intended to be overly complex - the real challenge is getting a program that can run correctly with protoc.

What is a plugin, and how do I write one?

A protoc plugin allows users to generate custom code according to the structured representation of Protobuf files. In simpler terms, plugins are programs that take Protobuf files as input, and produce code as output.

As you'll notice in some of the additional plugin documentation, the plugin must either be discoverable by your machine's PATH, or be manually targeted with the --plugin flag. In this case, we recommend placing the plugin on your PATH so that you can quickly go install between test invocations, but this is up to you.

For references, there are many examples of plugins you can find on the web.

What does the plugin need to do?

The plugin must be implemented in Go.

The plugin must output one YAML file for each of the input files specified in the protoc invocation.

The YAML file must conform to the following constraints:

  • The plugin is named protoc-gen-yaml.
  • The plugin outputs one YAML file for every input file.
  • Each of the files should be named by adding the .yaml suffix to their filename.
    • For example, an input file named proto/echo.proto will create proto/echo.proto.yaml.
  • The YAML output will represent a subset of the Protobuf file's content. Specifically, the plugin will create two maps in each file: one for messages and another for services. Each map key have a list of messages and services, respectively.
  • For each message, a list of fields will be represented under the fields key.
  • For each method, a list of methods will be represented under the methods key.

A template representation of the expected output is shown below. Pay close attention to the names of the map keys, as well as the required values associated with them.

If your are confused at all by any of these definitions, such as a field number, please refer to the Language Guide. The Testing section below gives an example that will make it easier to understand.

messages:
# For each message in this file, sorted by name...
- name: <$message_name>
  fields:
  # For each field in this message, sorted by number...
  - name: <$field_name>
    number: <$field_number>
services:
# For each service in this file, sorted by name...
- name: <$service_name>
  # For each method in this service, sorted by name...
  methods:
  - name: <$method_name>
    input_type: <$input_type>
    output_type: <$output_type>

Hint: Use Marshal from gopkg.in/yaml.v2 instead of using gopkg.in/yaml.v3 to get the correct indentation.

Testing

The following file located in test/input/proto/echo.proto.

syntax = "proto3";

package echo.v1;

message EchoRequest {
  string value = 1;
}

message EchoResponse {
  Foo foo = 1;
}

message Foo {
  message Bar {
    string value = 1;
  }
  string two = 2;
  string one = 1;
}

service EchoService {
  rpc Echo(EchoRequest) returns (EchoResponse);
}

Assuming that your plugin is installed in PATH, we should be able to execute the plugin like so:

$ protoc -I test/input test/input/proto/echo.proto --yaml_out=./output

The expected output for the test/input/proto/echo.proto file is shown below:

messages:
- name: echo.v1.EchoRequest
  fields:
  - name: value
    number: 1
- name: echo.v1.EchoResponse
  fields:
  - name: foo
    number: 1
- name: echo.v1.Foo
  fields:
  - name: one
    number: 1
  - name: two
    number: 2
- name: echo.v1.Foo.Bar
  fields:
  - name: value
    number: 1
services:
- name: echo.v1.EchoService
  methods:
  - name: Echo
    input_type: echo.v1.EchoRequest
    output_type: echo.v1.EchoResponse

You can verify if you've implemented the correct solution with diff:

$ protoc -I test/input test/input/proto/echo.proto --yaml_out=./output
$ diff ./output/proto/echo.proto.yaml ./test/output/proto/echo.proto.yaml

Note that the ouptut is sanitized, such that any . prefixes are trimmed in the relevant places. A proper solution will need to handle these cases, so pay special attention!

Submitting

Send a tar ball containing your solution and, optionally, any additional test cases you've created. We should be able to build the plugin with go build.

Similar Resources

A new way to create web applications using go and sdf framework.

SDF GO A new way to create web applications using go and sdf framework Explore the docs » View Demo · Report Bug · Request Feature Table of Contents A

Sep 27, 2022

A small site builder for the Gemini protocol

🐟 Flounder A lightweight platform to help users build simple Gemini sites over http(s) and serve those sites over http(s) and Gemini Flounder is in A

Dec 7, 2021

Official golang implementation of the Klaytn protocol

Klaytn Official golang implementation of the Klaytn protocol. Please visit KlaytnDocs for more details on Klaytn design, node operation guides and app

Nov 24, 2021

Baxos : a DDoS resistant consensus protocol based on Synod-Paxos

Baxos is a DDoS resistant consensus protocol based on Synod-Paxos. Baxos uses the Mage build tool. Therefore it needs the mage command to be installed

Jan 3, 2022

Protocol Generator API in Golang

PGen (building... learning GO Lang...) Protocol generator API in GO. The PGen is a microservice created to generate service protocols for any type of

Dec 20, 2021

Vela plugin designed for generating a static documentation website with Hugo.

Vela plugin designed for generating a static documentation website with Hugo.

Jul 22, 2022

an online REST renting book platform which you can authenticate, order, reserve a book in your account.

an online REST renting book platform which you can authenticate, order, reserve a book in your account.

BOOK MAN an online REST renting book platform which you can authenticate, order, reserve a book in your account. it's a microservices project with hig

Jul 22, 2022

This is a very simple web-app which simply always returns HTTP status code 200

Responder This is a very simple web-app which simply always returns HTTP status code 200. It will also wait for an amount of time which can be set in

Dec 14, 2021

A simple web application written in Golang which listens on port 8080

GoWebApp It's a simple web application written in Golang which listens on port 8080 Building It can be build using the command go build -o metricsweba

Oct 21, 2021
A little example about protobuf and Golang

Protocol buffers A little example about protobuf and Golang What is it? - IDL = interface description language - Multilenguage - Optimized serializati

Dec 15, 2021
Example golang using gin framework everything you need, i create this tutorial special for beginner.

Golang Gin Framework Fundamental Example golang using gin framework everything you need, i create this tutorial special for beginner. Feature Containe

Dec 16, 2022
Create a demo RESTful application using Golang

Instructions The goal of this exercise is to create a demo RESTful application using Golang. The Task In this task, we are building backend of an appl

Oct 30, 2021
Create a short link

Shortlink using a GCP Cloud Run Serverless example Make a Dir: mkdir shortlink && cd shortlink Clone: git clone https://github.com/tonnytg/shortlink.

Nov 26, 2021
This application is a tool to rapidly create TFS tasks and synchronize them with wiki.

This application is a tool to rapidly create TFS tasks and synchronize them with wiki.

Jan 10, 2022
Give developers an easy way to create and integrate bank processing into their own software products
Give developers an easy way to create and integrate bank processing into their own software products

Community · Blog moov-io/bankcron Moov's mission is to give developers an easy way to create and integrate bank processing into their own software pro

Sep 27, 2022
poCo: portable Containers. Create statically linked, portable binaries from container images (daemonless)
poCo: portable Containers. Create statically linked, portable binaries from container images (daemonless)

poCo Containers -> Binaries Create statically linked, portable binaries from container images A simple, static golang bundler! poCo (portable-Containe

Oct 25, 2022
Using golang framework (Gin) to create a web-application

News feeder Using golang framework (Gin) to create a web-application. This simpl

Aug 22, 2022
ging is a tool for create gin web framework development templates

ging ging is a tool for create gin web framework development templates This tool is for the freshmen who want to learn golang and gin web framework, i

Jan 15, 2022
Create Mermaid-Js ERD diagrams from existing tables

Mermerd Create Mermaid-Js ERD diagrams from existing tables. Features Supports PostgreSQL and MySQL Select from available schemas Select only the tabl

Dec 29, 2022