CINXE.COM
Protocol Buffer Basics: Go | Protocol Buffers Documentation
<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=generator content="Hugo 0.121.2"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffer Basics: Go | Protocol Buffers Documentation</title> <meta name=description content="A basic Go programmers introduction to working with protocol buffers."><meta property="og:title" content="Protocol Buffer Basics: Go"><meta property="og:description" content="A basic Go programmers introduction to working with protocol buffers."><meta property="og:type" content="article"><meta property="og:url" content="https://protobuf.dev/getting-started/gotutorial/"><meta property="article:section" content="getting-started"><meta itemprop=name content="Protocol Buffer Basics: Go"><meta itemprop=description content="A basic Go programmers introduction to working with protocol buffers."><meta itemprop=wordCount content="1818"><meta itemprop=keywords content><meta name=twitter:card content="summary"><meta name=twitter:title content="Protocol Buffer Basics: Go"><meta name=twitter:description content="A basic Go programmers introduction to working with protocol buffers."><link rel=preload href=/scss/main.min.6a57e8f3f347dea5d31cb48e3b4ea9fdae32d499473089bdef9b45457b5debb8.css as=style><link href=/scss/main.min.6a57e8f3f347dea5d31cb48e3b4ea9fdae32d499473089bdef9b45457b5debb8.css rel=stylesheet integrity><script src=https://code.jquery.com/jquery-3.6.0.min.js integrity=sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK crossorigin=anonymous></script><script async src="https://www.googletagmanager.com/gtag/js?id=G-5L8P8GRN4Y"></script><script>var doNotTrack=!1;if(!doNotTrack){window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date),gtag("config","G-5L8P8GRN4Y")}</script></head><body class=td-page><header><nav class="js-navbar-scroll navbar navbar-expand navbar-dark flex-column flex-md-row td-navbar"><a class=navbar-brand href=/><span class="navbar-brand__logo navbar-logo"></span><span class=navbar-brand__name>Protocol Buffers Documentation</span></a><div class="td-navbar-nav-scroll ml-md-auto" id=main_navbar><ul class="navbar-nav mt-2 mt-lg-0"></ul></div><div class="navbar-nav d-none d-lg-block"><div class=td-search><div class=td-search__icon></div><input type=search class="td-search__input form-control td-search-input" placeholder="Search this site…" aria-label="Search this site…" autocomplete=off></div></div></nav></header><div class="container-fluid td-outer"><div class=td-main><div class="row flex-xl-nowrap"><aside class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none"><div id=td-sidebar-menu class=td-sidebar__inner><div id=content-mobile><form class="td-sidebar__search d-flex align-items-center"><div class=td-search><div class=td-search__icon></div><input type=search class="td-search__input form-control td-search-input" placeholder="Search this site…" aria-label="Search this site…" autocomplete=off></div><button class="btn btn-link td-sidebar__toggle d-md-none p-0 ml-3 fas fa-bars" type=button data-toggle=collapse data-target=#td-section-nav aria-controls=td-section-nav aria-expanded=false aria-label="Toggle section navigation"></button></form></div><div id=content-desktop></div><nav class="collapse td-sidebar-nav" id=td-section-nav><ul class="td-sidebar-nav__section pr-md-3 ul-0"><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child active-path" id=m--li><a href=/ class="align-left pl-0 td-sidebar-link td-sidebar-link__section tree-root" id=m-><span>Protocol Buffers</span></a><ul class=ul-1><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-overview-li><a href=/overview/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-overview><span>Overview</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-news-li><a href=/news/ class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-news><span>News</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-programming-guides-li><a href=/programming-guides/ class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-programming-guides><span>Programming Guides</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guideseditions-li><a href=/programming-guides/editions/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guideseditions><span>Language Guide (editions)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesproto2-li><a href=/programming-guides/proto2/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesproto2><span>Language Guide (proto 2)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesproto3-li><a href=/programming-guides/proto3/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesproto3><span>Language Guide (proto 3)</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesproto-limits-li><a href=/programming-guides/proto-limits/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesproto-limits><span>Proto Limits</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesstyle-li><a href=/programming-guides/style/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesstyle><span>Style Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesenum-li><a href=/programming-guides/enum/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesenum><span>Enum Behavior</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesencoding-li><a href=/programming-guides/encoding/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesencoding><span>Encoding</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesjson-li><a href=/programming-guides/json/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesjson><span>ProtoJSON Format</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidestechniques-li><a href=/programming-guides/techniques/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidestechniques><span>Techniques</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesaddons-li><a href=/programming-guides/addons/ title="Third-Party Add-ons" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesaddons><span>Add-ons</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesextension_declarations-li><a href=/programming-guides/extension_declarations/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesextension_declarations><span>Extension Declarations</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesfield_presence-li><a href=/programming-guides/field_presence/ title="Application Note: Field Presence" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesfield_presence><span>Field Presence</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesserialization-not-canonical-li><a href=/programming-guides/serialization-not-canonical/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesserialization-not-canonical><span>Proto Serialization Is Not Canonical</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesnullable-getters-setters-li><a href=/programming-guides/nullable-getters-setters/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesnullable-getters-setters><span>No Nullable Setters/Getters Support</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesbest-practices-li><a href=/programming-guides/best-practices/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesbest-practices><span>Proto Best Practices</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesdos-donts-li><a href=/programming-guides/dos-donts/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesdos-donts><span>Proto Best Practices</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guidesapi-li><a href=/programming-guides/api/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guidesapi><span>API Best Practices</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-programming-guides1-1-1-li><a href=/programming-guides/1-1-1/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-programming-guides1-1-1><span>1-1-1 Best Practice</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-editions-li><a href=/editions/ class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-editions><span>Protobuf Editions</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-editionsoverview-li><a href=/editions/overview/ title="Protobuf Editions Overview" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-editionsoverview><span>Overview</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-editionsfeatures-li><a href=/editions/features/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-editionsfeatures><span>Feature Settings for Editions</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-editionsimplementation-li><a href=/editions/implementation/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-editionsimplementation><span>Implementing Editions Support</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child active-path" id=m-getting-started-li><a href=/getting-started/ class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-getting-started><span>Tutorials</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedcpptutorial-li><a href=/getting-started/cpptutorial/ title="Protocol Buffer Basics: C++" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedcpptutorial><span>C++</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedcsharptutorial-li><a href=/getting-started/csharptutorial/ title="Protocol Buffer Basics: C#" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedcsharptutorial><span>C#</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-starteddarttutorial-li><a href=/getting-started/darttutorial/ title="Protocol Buffer Basics: Dart" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-getting-starteddarttutorial><span>Dart</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child active-path" id=m-getting-startedgotutorial-li><a href=/getting-started/gotutorial/ title="Protocol Buffer Basics: Go" class="align-left pl-0 active td-sidebar-link td-sidebar-link__page" id=m-getting-startedgotutorial><span class=td-sidebar-nav-active-item>Go</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedjavatutorial-li><a href=/getting-started/javatutorial/ title="Protocol Buffer Basics: Java" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedjavatutorial><span>Java</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedkotlintutorial-li><a href=/getting-started/kotlintutorial/ title="Protocol Buffer Basics: Kotlin" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedkotlintutorial><span>Kotlin</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-getting-startedpythontutorial-li><a href=/getting-started/pythontutorial/ title="Protocol Buffer Basics: Python" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-getting-startedpythontutorial><span>Python</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-reference-li><a href=/reference/ class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-reference><span>Reference Guides</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencecpp-li><a href=/reference/cpp/ title="C++ Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencecpp><span>C++</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecppcpp-generated-li><a href=/reference/cpp/cpp-generated/ title="C++ Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencecppcpp-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecpparenas-li><a href=/reference/cpp/arenas/ title="C++ Arena Allocation Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencecpparenas><span>Arena Allocation Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecppabseil-li><a href=/reference/cpp/abseil/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencecppabseil><span>Asbseil Support</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecppapi-docs-link-li><a href=/reference/cpp/api-docs/ target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencecppapi-docs-link><span>C++ API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencecsharp-li><a href=/reference/csharp/ title="C# Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencecsharp><span>C#</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecsharpcsharp-generated-li><a href=/reference/csharp/csharp-generated/ title="C# Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencecsharpcsharp-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencecsharpapi-docs-link-li><a href=/reference/csharp/api-docs target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencecsharpapi-docs-link><span>C# API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencedart-li><a href=/reference/dart/ title="Dart Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencedart><span>Dart</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencedartdart-generated-li><a href=/reference/dart/dart-generated/ title="Dart Generated Code" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencedartdart-generated><span>Generated Code</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencedartapi-docs-link-li><a href=https://pub.dartlang.org/documentation/protobuf target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencedartapi-docs-link><span>Dart API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencego-li><a href=/reference/go/ title="Go Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencego><span>Go</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegogo-generated-li><a href=/reference/go/go-generated/ title="Go Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencegogo-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegofaq-li><a href=/reference/go/faq/ title="Go FAQ" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencegofaq><span>FAQ</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegosize-li><a href=/reference/go/size/ title="Go Size Semantics" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencegosize><span>Size Semantics</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencegoapi-docs-link-li><a href=https://pkg.go.dev/google.golang.org/protobuf/proto target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencegoapi-docs-link><span>Go API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencejava-li><a href=/reference/java/ title="Java Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencejava><span>Java</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencejavajava-generated-li><a href=/reference/java/java-generated/ title="Java Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencejavajava-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencejavajava-proto-names-li><a href=/reference/java/java-proto-names/ title="Java Proto Names" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencejavajava-proto-names><span>Generated Proto Names</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencejavaapi-docs-link-li><a href=/reference/java/api-docs/overview-summary.html target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencejavaapi-docs-link><span>Java API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencekotlin-li><a href=/reference/kotlin/ title="Kotlin Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencekotlin><span>Kotlin</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencekotlinapi-docs-li><a href=/reference/kotlin/api-docs/ title="Kotlin Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencekotlinapi-docs><span>Kotlin</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencekotlinkotlin-generated-li><a href=/reference/kotlin/kotlin-generated/ title="Kotlin Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencekotlinkotlin-generated><span>Generated Code Guide</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referenceobjective-c-li><a href=/reference/objective-c/ title="Objective-C Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referenceobjective-c><span>Objective-C</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceobjective-cobjective-c-generated-li><a href=/reference/objective-c/objective-c-generated/ title="Objective-C Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referenceobjective-cobjective-c-generated><span>Generated Code Guide</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencephp-li><a href=/reference/php/ title="PHP Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencephp><span>PHP</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencephpphp-generated-li><a href=/reference/php/php-generated/ title="PHP Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencephpphp-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencephpapi-docs-link-li><a href=/reference/php/api-docs/ target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencephpapi-docs-link><span>PHP API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referencepython-li><a href=/reference/python/ title="Python Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referencepython><span>Python</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencepythonpython-generated-li><a href=/reference/python/python-generated/ title="Python Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencepythonpython-generated><span>Generated Code Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencepythonapi-docs-link-li><a href=https://googleapis.dev/python/protobuf/latest/ target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencepythonapi-docs-link><span>Python API</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referenceruby-li><a href=/reference/ruby/ title="Ruby Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referenceruby><span>Ruby</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referencerubyruby-generated-li><a href=/reference/ruby/ruby-generated/ title="Ruby Generated Code Guide" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referencerubyruby-generated><span>Generated Code Guide</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-referenceprotobuf-li><a href=/reference/protobuf/ title="Protocol Buffers Reference" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-referenceprotobuf><span>Protocol Buffers</span></a><ul class="ul-3 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufedition-2023-spec-li><a href=/reference/protobuf/edition-2023-spec/ title="Protocol Buffers Edition 2023 Language Specification" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufedition-2023-spec><span>2023 Language Specification</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufproto2-spec-li><a href=/reference/protobuf/proto2-spec/ title="Protocol Buffers Version 2 Language Specification" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufproto2-spec><span>Version 2 Language Specification</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufproto3-spec-li><a href=/reference/protobuf/proto3-spec/ title="Protocol Buffers Version 3 Language Specification" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufproto3-spec><span>Version 3 Language Specification</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobuftextformat-spec-li><a href=/reference/protobuf/textformat-spec/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobuftextformat-spec><span>Text Format Language Specification</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceprotobufgoogleprotobuf-li><a href=/reference/protobuf/google.protobuf/ title="Protocol Buffers Well-Known Types" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referenceprotobufgoogleprotobuf><span>Well-Known Types</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-referenceother-li><a href=/reference/other/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-referenceother><span>Other Languages</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-support-li><a href=/support/ class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-support><span>Support</span></a><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-supportversion-support-li><a href=/support/version-support/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-supportversion-support><span>Version Support</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-supportmigration-li><a href=/support/migration/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-supportmigration><span>Migration Guide</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-supportcross-version-runtime-guarantee-li><a href=/support/cross-version-runtime-guarantee/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-supportcross-version-runtime-guarantee><span>Cross-Version Runtime Guarantee</span></a></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-downloads-li><a href=/downloads/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-downloads><span>Downloads</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-history-li><a href=/history/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-history><span>History</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-forum-link-li><a href=https://groups.google.com/g/protobuf target=_blank rel=noopener class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-forum-link><span>Forum</span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-navbar-li><a href=/navbar/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-navbar><span></span></a></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-search-li><a href=/search/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-search><span>Search Results</span></a></li></ul></li></ul></nav></div></aside><aside class="d-none d-xl-block col-xl-2 td-sidebar-toc d-print-none"><div class="td-page-meta ml-2 pb-1 pt-2 mb-0"><a href=https://github.com/protocolbuffers/protocolbuffers.github.io/tree/main/content/getting-started/gotutorial.md class=td-page-meta--view target=_blank rel=noopener><i class="fa-solid fa-file-lines fa-fw"></i> View page source</a> <a href=https://github.com/protocolbuffers/protocolbuffers.github.io/edit/main/content/getting-started/gotutorial.md class=td-page-meta--edit target=_blank rel=noopener><i class="fa-solid fa-pen-to-square fa-fw"></i> Edit this page</a> <a href="https://github.com/protocolbuffers/protocolbuffers.github.io/new/main/content/getting-started/gotutorial.md?filename=change-me.md&value=---%0Atitle%3A+%22Long+Page+Title%22%0AlinkTitle%3A+%22Short+Nav+Title%22%0Aweight%3A+100%0Adescription%3A+%3E-%0A+++++Page+description+for+heading+and+indexes.%0A---%0A%0A%23%23+Heading%0A%0AEdit+this+template+to+create+your+new+page.%0A%0A%2A+Give+it+a+good+name%2C+ending+in+%60.md%60+-+e.g.+%60getting-started.md%60%0A%2A+Edit+the+%22front+matter%22+section+at+the+top+of+the+page+%28weight+controls+how+its+ordered+amongst+other+pages+in+the+same+directory%3B+lowest+number+first%29.%0A%2A+Add+a+good+commit+message+at+the+bottom+of+the+page+%28%3C80+characters%3B+use+the+extended+description+field+for+more+detail%29.%0A%2A+Create+a+new+branch+so+you+can+preview+your+new+file+and+request+a+review+via+Pull+Request.%0A" class=td-page-meta--child target=_blank rel=noopener><i class="fa-solid fa-pen-to-square fa-fw"></i> Create child page</a> <a href="https://github.com/protocolbuffers/protocolbuffers.github.io/issues/new?title=Protocol%20Buffer%20Basics:%20Go" class=td-page-meta--issue target=_blank rel=noopener><i class="fa-solid fa-list-check fa-fw"></i> Create documentation issue</a> <a href=https://github.com/protocolbuffers/protobuf/issues/new class=td-page-meta--project-issue target=_blank rel=noopener><i class="fa-solid fa-list-check fa-fw"></i> Create project issue</a></div><div class=td-toc><nav id=TableOfContents><ul><li><a href=#problem-domain>The Problem Domain</a></li><li><a href=#example-code>Where to Find the Example Code</a></li><li><a href=#protocol-format>Defining Your Protocol Format</a></li><li><a href=#compiling-protocol-buffers>Compiling Your Protocol Buffers</a></li><li><a href=#protobuf-api>The Protocol Buffer API</a></li><li><a href=#writing-a-message>Writing a Message</a></li><li><a href=#reading-a-message>Reading a Message</a></li><li><a href=#extending-a-protobuf>Extending a Protocol Buffer</a></li></ul></nav></div></aside><main class="col-12 col-md-9 col-xl-8 pl-md-5" role=main><nav aria-label=breadcrumb class=td-breadcrumbs><ol class=breadcrumb><li class=breadcrumb-item><a href=https://protobuf.dev/getting-started/>Tutorials</a></li><li class="breadcrumb-item active" aria-current=page><a href=https://protobuf.dev/getting-started/gotutorial/ aria-disabled=true class="btn-link disabled">Go</a></li></ol></nav><div class=td-content><h1>Protocol Buffer Basics: Go</h1><div class=lead>A basic Go programmers introduction to working with protocol buffers.</div><header class=article-meta></header><p>This tutorial provides a basic Go programmer’s introduction to working with protocol buffers, using the <a href=/programming-guides/proto3>proto3</a> version of the protocol buffers language. By walking through creating a simple example application, it shows you how to</p><ul><li>Define message formats in a <code>.proto</code> file.</li><li>Use the protocol buffer compiler.</li><li>Use the Go protocol buffer API to write and read messages.</li></ul><p>This isn’t a comprehensive guide to using protocol buffers in Go. For more detailed reference information, see the <a href=/programming-guides/proto3>Protocol Buffer Language Guide</a>, the <a href=https://pkg.go.dev/google.golang.org/protobuf/proto>Go API Reference</a>, the <a href=/reference/go/go-generated>Go Generated Code Guide</a>, and the <a href=/programming-guides/encoding>Encoding Reference</a>.</p><h2 id=problem-domain>The Problem Domain</h2><p>The example we’re going to use is a very simple “address book” application that can read and write people’s contact details to and from a file. Each person in the address book has a name, an ID, an email address, and a contact phone number.</p><p>How do you serialize and retrieve structured data like this? There are a few ways to solve this problem:</p><ul><li>Use <a href=//golang.org/pkg/encoding/gob/>gobs</a> to serialize Go data structures. This is a good solution in a Go-specific environment, but it doesn’t work well if you need to share data with applications written for other platforms.</li><li>You can invent an ad-hoc way to encode the data items into a single string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and flexible approach, although it does require writing one-off encoding and parsing code, and the parsing imposes a small run-time cost. This works best for encoding very simple data.</li><li>Serialize the data to XML. This approach can be very attractive since XML is (sort of) human readable and there are binding libraries for lots of languages. This can be a good choice if you want to share data with other applications/projects. However, XML is notoriously space intensive, and encoding/decoding it can impose a huge performance penalty on applications. Also, navigating an XML DOM tree is considerably more complicated than navigating simple fields in a class normally would be.</li></ul><p>Protocol buffers are the flexible, efficient, automated solution to solve exactly this problem. With protocol buffers, you write a <code>.proto</code> description of the data structure you wish to store. From that, the protocol buffer compiler creates a class that implements automatic encoding and parsing of the protocol buffer data with an efficient binary format. The generated class provides getters and setters for the fields that make up a protocol buffer and takes care of the details of reading and writing the protocol buffer as a unit. Importantly, the protocol buffer format supports the idea of extending the format over time in such a way that the code can still read data encoded with the old format.</p><h2 id=example-code>Where to Find the Example Code</h2><p>Our example is a set of command-line applications for managing an address book data file, encoded using protocol buffers. The command <code>add_person_go</code> adds a new entry to the data file. The command <code>list_people_go</code> parses the data file and prints the data to the console.</p><p>You can find the complete example in the <a href=https://github.com/protocolbuffers/protobuf/tree/master/examples>examples directory</a> of the GitHub repository.</p><h2 id=protocol-format>Defining Your Protocol Format</h2><p>To create your address book application, you’ll need to start with a <code>.proto</code> file. The definitions in a <code>.proto</code> file are simple: you add a <em>message</em> for each data structure you want to serialize, then specify a name and a type for each field in the message. In our example, the <code>.proto</code> file that defines the messages is <a href=https://github.com/protocolbuffers/protobuf/blob/master/examples/addressbook.proto><code>addressbook.proto</code></a>.</p><p>The <code>.proto</code> file starts with a package declaration, which helps to prevent naming conflicts between different projects.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-proto data-lang=proto><span style=display:flex><span><span style=color:#000>syntax</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>"proto3"</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#204a87;font-weight:700>package</span> <span style=color:#000>tutorial</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#4e9a06>"google/protobuf/timestamp.proto"</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span></code></pre></div><p>The <code>go_package</code> option defines the import path of the package which will contain all the generated code for this file. The Go package name will be the last path component of the import path. For example, our example will use a package name of “tutorialpb”.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-proto data-lang=proto><span style=display:flex><span><span style=color:#204a87;font-weight:700>option</span> <span style=color:#000>go_package</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#4e9a06>"github.com/protocolbuffers/protobuf/examples/go/tutorialpb"</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span></code></pre></div><p>Next, you have your message definitions. A message is just an aggregate containing a set of typed fields. Many standard simple data types are available as field types, including <code>bool</code>, <code>int32</code>, <code>float</code>, <code>double</code>, and <code>string</code>. You can also add further structure to your messages by using other message types as field types.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-proto data-lang=proto><span style=display:flex><span><span style=color:#204a87;font-weight:700>message</span> <span style=color:#000>Person</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>string</span> <span style=color:#000>name</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>int32</span> <span style=color:#000>id</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>2</span><span style=color:#000;font-weight:700>;</span> <span style=color:#8f5902;font-style:italic>// Unique ID number for this person. </span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>string</span> <span style=color:#000>email</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>3</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>message</span> <span style=color:#000>PhoneNumber</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>string</span> <span style=color:#000>number</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PhoneType</span> <span style=color:#000>type</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>2</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000;font-weight:700>}</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>repeated</span> <span style=color:#000>PhoneNumber</span> <span style=color:#000>phones</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>4</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>google.protobuf.Timestamp</span> <span style=color:#000>last_updated</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>5</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#000;font-weight:700>}</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#204a87;font-weight:700>enum</span> <span style=color:#000>PhoneType</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_UNSPECIFIED</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>0</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_MOBILE</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_HOME</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>2</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#000>PHONE_TYPE_WORK</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>3</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#000;font-weight:700>}</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#8f5902;font-style:italic>// Our address book file is just one of these. </span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span><span style=color:#204a87;font-weight:700>message</span> <span style=color:#000>AddressBook</span> <span style=color:#000;font-weight:700>{</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span> <span style=color:#204a87;font-weight:700>repeated</span> <span style=color:#000>Person</span> <span style=color:#000>people</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#0000cf;font-weight:700>1</span><span style=color:#000;font-weight:700>;</span><span style=color:#a40000> </span></span></span><span style=display:flex><span><span style=color:#a40000></span><span style=color:#000;font-weight:700>}</span><span style=color:#a40000> </span></span></span></code></pre></div><p>In the above example, the <code>Person</code> message contains <code>PhoneNumber</code> messages, while the <code>AddressBook</code> message contains <code>Person</code> messages. You can even define message types nested inside other messages – as you can see, the <code>PhoneNumber</code> type is defined inside <code>Person</code>. You can also define <code>enum</code> types if you want one of your fields to have one of a predefined list of values – here you want to specify that a phone number can be one of <code>PHONE_TYPE_MOBILE</code>, <code>PHONE_TYPE_HOME</code>, or <code>PHONE_TYPE_WORK</code>.</p><p>The " = 1", " = 2" markers on each element identify the unique “tag” that field uses in the binary encoding. Tag numbers 1-15 require one less byte to encode than higher numbers, so as an optimization you can decide to use those tags for the commonly used or repeated elements, leaving tags 16 and higher for less-commonly used optional elements. Each element in a repeated field requires re-encoding the tag number, so repeated fields are particularly good candidates for this optimization.</p><p>If a field value isn’t set, a <a href=/programming-guides/proto3#default>default value</a> is used: zero for numeric types, the empty string for strings, false for bools. For embedded messages, the default value is always the “default instance” or “prototype” of the message, which has none of its fields set. Calling the accessor to get the value of a field which has not been explicitly set always returns that field’s default value.</p><p>If a field is <code>repeated</code>, the field may be repeated any number of times (including zero). The order of the repeated values will be preserved in the protocol buffer. Think of repeated fields as dynamically sized arrays.</p><p>You’ll find a complete guide to writing <code>.proto</code> files – including all the possible field types – in the <a href=/programming-guides/proto3>Protocol Buffer Language Guide</a>. Don’t go looking for facilities similar to class inheritance, though – protocol buffers don’t do that.</p><h2 id=compiling-protocol-buffers>Compiling Your Protocol Buffers</h2><p>Now that you have a <code>.proto</code>, the next thing you need to do is generate the classes you’ll need to read and write <code>AddressBook</code> (and hence <code>Person</code> and <code>PhoneNumber</code>) messages. To do this, you need to run the protocol buffer compiler <code>protoc</code> on your <code>.proto</code>:</p><ol><li><p>If you haven’t installed the compiler, <a href=/downloads>download the package</a> and follow the instructions in the README.</p></li><li><p>Run the following command to install the Go protocol buffers plugin:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>go install google.golang.org/protobuf/cmd/protoc-gen-go@latest </span></span></code></pre></div><p>The compiler plugin <code>protoc-gen-go</code> will be installed in <code>$GOBIN</code>, defaulting to <code>$GOPATH/bin</code>. It must be in your <code>$PATH</code> for the protocol compiler <code>protoc</code> to find it.</p></li><li><p>Now run the compiler, specifying the source directory (where your application’s source code lives – the current directory is used if you don’t provide a value), the destination directory (where you want the generated code to go; often the same as <code>$SRC_DIR</code>), and the path to your <code>.proto</code>. In this case, you would invoke:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>protoc -I<span style=color:#ce5c00;font-weight:700>=</span><span style=color:#000>$SRC_DIR</span> --go_out<span style=color:#ce5c00;font-weight:700>=</span><span style=color:#000>$DST_DIR</span> <span style=color:#000>$SRC_DIR</span>/addressbook.proto </span></span></code></pre></div><p>Because you want Go code, you use the <code>--go_out</code> option – similar options are provided for other supported languages.</p></li></ol><p>This generates <code>github.com/protocolbuffers/protobuf/examples/go/tutorialpb/addressbook.pb.go</code> in your specified destination directory.</p><h2 id=protobuf-api>The Protocol Buffer API</h2><p>Generating <code>addressbook.pb.go</code> gives you the following useful types:</p><ul><li>An <code>AddressBook</code> structure with a <code>People</code> field.</li><li>A <code>Person</code> structure with fields for <code>Name</code>, <code>Id</code>, <code>Email</code> and <code>Phones</code>.</li><li>A <code>Person_PhoneNumber</code> structure, with fields for <code>Number</code> and <code>Type</code>.</li><li>The type <code>Person_PhoneType</code> and a value defined for each value in the <code>Person.PhoneType</code> enum.</li></ul><p>You can read more about the details of exactly what’s generated in the <a href=/reference/go/go-generated>Go Generated Code guide</a>, but for the most part you can treat these as perfectly ordinary Go types.</p><p>Here’s an example from the <a href=https://github.com/protocolbuffers/protobuf/blob/master/examples/go/cmd/list_people/list_people_test.go><code>list_people</code> command’s unit tests</a> of how you might create an instance of Person:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span><span style=color:#000>p</span> <span style=color:#ce5c00;font-weight:700>:=</span> <span style=color:#000>pb</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Person</span><span style=color:#000;font-weight:700>{</span> </span></span><span style=display:flex><span> <span style=color:#000>Id</span><span style=color:#000;font-weight:700>:</span> <span style=color:#0000cf;font-weight:700>1234</span><span style=color:#000;font-weight:700>,</span> </span></span><span style=display:flex><span> <span style=color:#000>Name</span><span style=color:#000;font-weight:700>:</span> <span style=color:#4e9a06>"John Doe"</span><span style=color:#000;font-weight:700>,</span> </span></span><span style=display:flex><span> <span style=color:#000>Email</span><span style=color:#000;font-weight:700>:</span> <span style=color:#4e9a06>"jdoe@example.com"</span><span style=color:#000;font-weight:700>,</span> </span></span><span style=display:flex><span> <span style=color:#000>Phones</span><span style=color:#000;font-weight:700>:</span> <span style=color:#000;font-weight:700>[]</span><span style=color:#ce5c00;font-weight:700>*</span><span style=color:#000>pb</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Person_PhoneNumber</span><span style=color:#000;font-weight:700>{</span> </span></span><span style=display:flex><span> <span style=color:#000;font-weight:700>{</span><span style=color:#000>Number</span><span style=color:#000;font-weight:700>:</span> <span style=color:#4e9a06>"555-4321"</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>Type</span><span style=color:#000;font-weight:700>:</span> <span style=color:#000>pb</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>PhoneType_PHONE_TYPE_HOME</span><span style=color:#000;font-weight:700>},</span> </span></span><span style=display:flex><span> <span style=color:#000;font-weight:700>},</span> </span></span><span style=display:flex><span><span style=color:#000;font-weight:700>}</span> </span></span></code></pre></div><h2 id=writing-a-message>Writing a Message</h2><p>The whole purpose of using protocol buffers is to serialize your data so that it can be parsed elsewhere. In Go, you use the <code>proto</code> library’s <a href="https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Marshal">Marshal</a> function to serialize your protocol buffer data. A pointer to a protocol buffer message’s <code>struct</code> implements the <code>proto.Message</code> interface. Calling <code>proto.Marshal</code> returns the protocol buffer, encoded in its wire format. For example, we use this function in the <a href=https://github.com/protocolbuffers/protobuf/blob/master/examples/go/cmd/add_person/add_person.go><code>add_person</code> command</a>:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span><span style=color:#000>book</span> <span style=color:#ce5c00;font-weight:700>:=</span> <span style=color:#ce5c00;font-weight:700>&</span><span style=color:#000>pb</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>AddressBook</span><span style=color:#000;font-weight:700>{}</span> </span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic>// ... </span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> </span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic>// Write the new address book back to disk. </span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span><span style=color:#000>out</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>:=</span> <span style=color:#000>proto</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Marshal</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>book</span><span style=color:#000;font-weight:700>)</span> </span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>!=</span> <span style=color:#204a87;font-weight:700>nil</span> <span style=color:#000;font-weight:700>{</span> </span></span><span style=display:flex><span> <span style=color:#000>log</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Fatalln</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>"Failed to encode address book:"</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>err</span><span style=color:#000;font-weight:700>)</span> </span></span><span style=display:flex><span><span style=color:#000;font-weight:700>}</span> </span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>:=</span> <span style=color:#000>ioutil</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>WriteFile</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>fname</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>out</span><span style=color:#000;font-weight:700>,</span> <span style=color:#0000cf;font-weight:700>0644</span><span style=color:#000;font-weight:700>);</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>!=</span> <span style=color:#204a87;font-weight:700>nil</span> <span style=color:#000;font-weight:700>{</span> </span></span><span style=display:flex><span> <span style=color:#000>log</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Fatalln</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>"Failed to write address book:"</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>err</span><span style=color:#000;font-weight:700>)</span> </span></span><span style=display:flex><span><span style=color:#000;font-weight:700>}</span> </span></span></code></pre></div><h2 id=reading-a-message>Reading a Message</h2><p>To parse an encoded message, you use the <code>proto</code> library’s <a href="https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Unmarshal">Unmarshal</a> function. Calling this parses the data in <code>in</code> as a protocol buffer and places the result in <code>book</code>. So to parse the file in the <a href=https://github.com/protocolbuffers/protobuf/blob/master/examples/go/cmd/list_people/list_people.go><code>list_people</code> command</a>, we use:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-go data-lang=go><span style=display:flex><span><span style=color:#8f5902;font-style:italic>// Read the existing address book. </span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span><span style=color:#000>in</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>:=</span> <span style=color:#000>ioutil</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>ReadFile</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>fname</span><span style=color:#000;font-weight:700>)</span> </span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>!=</span> <span style=color:#204a87;font-weight:700>nil</span> <span style=color:#000;font-weight:700>{</span> </span></span><span style=display:flex><span> <span style=color:#000>log</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Fatalln</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>"Error reading file:"</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>err</span><span style=color:#000;font-weight:700>)</span> </span></span><span style=display:flex><span><span style=color:#000;font-weight:700>}</span> </span></span><span style=display:flex><span><span style=color:#000>book</span> <span style=color:#ce5c00;font-weight:700>:=</span> <span style=color:#ce5c00;font-weight:700>&</span><span style=color:#000>pb</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>AddressBook</span><span style=color:#000;font-weight:700>{}</span> </span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>if</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>:=</span> <span style=color:#000>proto</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Unmarshal</span><span style=color:#000;font-weight:700>(</span><span style=color:#000>in</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>book</span><span style=color:#000;font-weight:700>);</span> <span style=color:#000>err</span> <span style=color:#ce5c00;font-weight:700>!=</span> <span style=color:#204a87;font-weight:700>nil</span> <span style=color:#000;font-weight:700>{</span> </span></span><span style=display:flex><span> <span style=color:#000>log</span><span style=color:#000;font-weight:700>.</span><span style=color:#000>Fatalln</span><span style=color:#000;font-weight:700>(</span><span style=color:#4e9a06>"Failed to parse address book:"</span><span style=color:#000;font-weight:700>,</span> <span style=color:#000>err</span><span style=color:#000;font-weight:700>)</span> </span></span><span style=display:flex><span><span style=color:#000;font-weight:700>}</span> </span></span></code></pre></div><h2 id=extending-a-protobuf>Extending a Protocol Buffer</h2><p>Sooner or later after you release the code that uses your protocol buffer, you will undoubtedly want to “improve” the protocol buffer’s definition. If you want your new buffers to be backwards-compatible, and your old buffers to be forward-compatible – and you almost certainly do want this – then there are some rules you need to follow. In the new version of the protocol buffer:</p><ul><li>you <em>must not</em> change the tag numbers of any existing fields.</li><li>you <em>may</em> delete fields.</li><li>you <em>may</em> add new fields but you must use fresh tag numbers (i.e. tag numbers that were never used in this protocol buffer, not even by deleted fields).</li></ul><p>(There are <a href=/programming-guides/proto3#updating>some exceptions</a> to these rules, but they are rarely used.)</p><p>If you follow these rules, old code will happily read new messages and simply ignore any new fields. To the old code, singular fields that were deleted will simply have their default value, and deleted repeated fields will be empty. New code will also transparently read old messages.</p><p>However, keep in mind that new fields will not be present in old messages, so you will need to do something reasonable with the default value. A type-specific <a href=/programming-guides/proto3#default>default value</a> is used: for strings, the default value is the empty string. For booleans, the default value is false. For numeric types, the default value is zero.</p></div></main></div></div><footer class="bg-dark py-5 row d-print-none"><div class="container-fluid mx-sm-5"><div class=row><div class="col-6 col-sm-4 text-xs-center order-sm-2"><ul class="list-inline mb-0"><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title="Stack Overflow" aria-label="Stack Overflow"><a class=text-white target=_blank rel=noopener href=https://stackoverflow.com/questions/tagged/protocol-buffers aria-label="Stack Overflow"><i class="fab fa-stack-overflow"></i></a></li></ul><script type=text/javascript id=cookiebanner src=https://cdn.jsdelivr.net/gh/dobarkod/cookie-banner@1.2.2/dist/cookiebanner.min.js data-height=50px data-message="Protobuf.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic." data-bg=#ffb data-fg=#000 data-position=bottom data-padding="10px 16px" data-close-text="OK, got it" data-font-size=18px data-moreinfo=https://policies.google.com/technologies/cookies></script></div><div class="col-6 col-sm-4 text-right text-xs-center order-sm-3"><ul class="list-inline mb-0"><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title=GitHub aria-label=GitHub><a class=text-white target=_blank rel=noopener href=https://github.com/protocolbuffers/protobuf aria-label=GitHub><i class="fab fa-github"></i></a></li><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title="Developer mailing list" aria-label="Developer mailing list"><a class=text-white target=_blank rel=noopener href=https://groups.google.com/g/protobuf aria-label="Developer mailing list"><i class="fa fa-envelope"></i></a></li></ul><script type=text/javascript id=cookiebanner src=https://cdn.jsdelivr.net/gh/dobarkod/cookie-banner@1.2.2/dist/cookiebanner.min.js data-height=50px data-message="Protobuf.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic." data-bg=#ffb data-fg=#000 data-position=bottom data-padding="10px 16px" data-close-text="OK, got it" data-font-size=18px data-moreinfo=https://policies.google.com/technologies/cookies></script></div><div class="col-12 col-sm-4 text-center py-2 order-sm-2"><small class=text-white>© 2024 Google LLC All Rights Reserved</small> <small class=ml-1><a href=https://policies.google.com/privacy target=_blank rel=noopener>Privacy Policy</a></small> <span class=text-white>Hosted by GitHub Pages.</span> <a href=https://docs.github.com/en/site-policy/privacy-policies/github-privacy-statement target=_blank>GitHub Privacy Statement</a></div></div></div></footer></div><script src=/js/main.min.ba08a6b7f24e657f0a1b9b55be3a3162585168cd862ace0957f5b44e6cb6dc61.js integrity="sha256-ugimt/JOZX8KG5tVvjoxYlhRaM2GKs4JV/W0Tmy23GE=" crossorigin=anonymous></script><script src=/js/tabpane-persist.js></script></body></html>