Repository: anz-bank/sysl
Pull request #495 (2020-01-01 06:37:51)

Feature/refactor listener
Some structural refactoring of the antlr parser listener to allow for parser simplification to follow...

BasicallyI noticed that the code was reusing struct fields in multiple places for different purposes which meant makes working in this codebase hell.

* Splits usages of `s.typename []string` into distinct fields for each of its uses (including:)
      1. keeping track of names used to build up references to types
      1. endpoint paths
      1. collector paths
      1. view names(!)
* Adds a simple stack type to replace the multiple ad-hock stacks that are used with the `typename` and `url_prefix` fields
* Replace the repeated map lookup to get the current modules app with a helper func

@anz-bank/sysl-developers


Reviewers: I would look at the commits indivually instead of the full diff, each is self contained.


Patch:
diff --git a/pkg/parse/listener_impl.go b/pkg/parse/listener_impl.go
index 590e41f0..9397c821 100644
--- a/pkg/parse/listener_impl.go
+++ b/pkg/parse/listener_impl.go
@@ -26,15 +26,19 @@ type importDef struct {
 // TreeShapeListener ..
 type TreeShapeListener struct {
 	*parser.BaseSyslParserListener
-	base                  string
-	sc                    sourceCtxHelper
-	imports               []importDef
-	module                *sysl.Module
-	appname               string
-	typename              string
+	base         string
+	sc           sourceCtxHelper
+	imports      []importDef
+	module       *sysl.Module
+	endpointName string
+
+	app             *sysl.Application
+	currentTypePath PathStack
+	viewName        string
+
 	fieldname             []string
-	url_prefix            []string
-	app_name              []string
+	urlPrefixes           PathStack
+	app_name              PathStack
 	annotation            string
 	typemap               map[string]*sysl.Type
 	prevLineEmpty         bool
@@ -70,19 +74,26 @@ func NewTreeShapeListener() *TreeShapeListener {
 		module: &sysl.Module{
 			Apps: map[string]*sysl.Application{},
 		},
-		opmap: opmap,
+		opmap:           opmap,
+		currentTypePath: NewPathStack("."),
+		urlPrefixes:     NewPathStack(""),
+		app_name:        NewPathStack(" :: "),
 	}
 }
 
+func (s *TreeShapeListener) currentApp() *sysl.Application {
+	return s.app
+}
+
 // EnterName_str is called when production name_str is entered.
 func (s *TreeShapeListener) EnterName_str(ctx *parser.Name_strContext) {
-	s.app_name = append(s.app_name, ctx.GetText())
+	s.app_name.Push(ctx.GetText())
 }
 
 // EnterReference is called when production reference is entered.
 func (s *TreeShapeListener) EnterReference(*parser.ReferenceContext) {
-	context_app_part := s.module.Apps[s.appname].Name.Part
-	context_path := strings.Split(s.typename, ".")
+	context_app_part := s.currentApp().Name.Part
+	context_path := s.currentTypePath.Parts()
 
 	s.currentType().Type = &sysl.Type_TypeRef{
 		TypeRef: &sysl.ScopedRef{
@@ -94,12 +105,12 @@ func (s *TreeShapeListener) EnterReference(*parser.ReferenceContext) {
 			},
 		},
 	}
-	s.app_name = []string{}
+	s.app_name.Reset()
 }
 
 // ExitReference is called when production reference is exited.
 func (s *TreeShapeListener) ExitReference(ctx *parser.ReferenceContext) {
-	s.currentType().GetTypeRef().Ref = makeScope(s.app_name, ctx)
+	s.currentType().GetTypeRef().Ref = makeScope(s.app_name.Parts(), ctx)
 }
 
 func lastTwoChars(str string) string {
@@ -116,7 +127,7 @@ func (s *TreeShapeListener) EnterDoc_string(ctx *parser.Doc_stringContext) {
 		text = strings.Replace(text, `"`, `\"`, -1)
 		text = fromQString(`"` + text[1:] + `"`)
 
-		if s.module.Apps[s.appname].Endpoints[s.typename].GetRestParams() != nil {
+		if s.currentApp().Endpoints[s.endpointName].GetRestParams() != nil {
 			if x := s.peekScope().(*sysl.Endpoint); x != nil && len(x.Stmt) == 0 {
 				if len(x.Docstring) > 0 {
 					space = " "
@@ -220,8 +231,8 @@ func (s *TreeShapeListener) EnterUser_defined_type(ctx *parser.User_defined_type
 	}
 	type1 := s.typemap[s.fieldname[len(s.fieldname)-1]]
 
-	context_app_part := s.module.Apps[s.appname].Name.Part
-	context_path := strings.Split(s.typename, ".")
+	context_app_part := s.currentApp().Name.Part
+	context_path := s.currentTypePath.Parts()
 	ref_path := []string{ctx.GetText()}
 
 	type1.Type = &sysl.Type_TypeRef{
@@ -302,7 +313,7 @@ func (s *TreeShapeListener) ExitAnnotation(*parser.AnnotationContext) {
 
 // EnterField_type is called when production field_type is entered.
 func (s *TreeShapeListener) EnterField_type(ctx *parser.Field_typeContext) {
-	s.app_name = []string{}
+	s.app_name.Reset()
 	type1 := s.typemap[s.fieldname[len(s.fieldname)-1]]
 
 	if attribs, ok := ctx.Attribs_or_modifiers().(*parser.Attribs_or_modifiersContext); ok {
@@ -312,11 +323,7 @@ func (s *TreeShapeListener) EnterField_type(ctx *parser.Field_typeContext) {
 	if ctx.QN() != nil {
 		type1.Opt = true
 	}
-	type1.SourceContext = &sysl.SourceContext{
-		Start: &sysl.SourceContext_Location{
-			Line: int32(ctx.GetStart().GetLine()),
-		},
-	}
+	type1.SourceContext = s.sc.Get(ctx.BaseParserRuleContext)
 
 	if ctx.Annotations() != nil {
 		if type1.Attrs == nil {
@@ -513,9 +520,9 @@ func makeAttributeArray(attribs *parser.Attribs_or_modifiersContext) map[string]
 
 // EnterInplace_tuple is called when production inplace_tuple is entered.
 func (s *TreeShapeListener) EnterInplace_tuple(*parser.Inplace_tupleContext) {
-	s.typename = s.typename + "." + s.fieldname[len(s.fieldname)-1]
+	s.currentTypePath.Push(s.fieldname[len(s.fieldname)-1])
 	s.typemap = map[string]*sysl.Type{}
-	s.module.Apps[s.appname].Types[s.typename] = &sysl.Type{
+	s.currentApp().Types[s.currentTypePath.Get()] = &sysl.Type{
 		Type: &sysl.Type_Tuple_{
 			Tuple: &sysl.Type_Tuple{
 				AttrDefs: s.typemap,
@@ -526,10 +533,9 @@ func (s *TreeShapeListener) EnterInplace_tuple(*parser.Inplace_tupleContext) {
 
 // ExitInplace_tuple is called when production inplace_tuple is exited.
 func (s *TreeShapeListener) ExitInplace_tuple(*parser.Inplace_tupleContext) {
-	fixFieldDefinitions(s.module.Apps[s.appname].Types[s.typename])
-	l := strings.LastIndex(s.typename, ".")
-	s.typename = s.typename[:l]
-	s.typemap = s.module.Apps[s.appname].Types[s.typename].GetTuple().GetAttrDefs()
+	fixFieldDefinitions(s.currentApp().Types[s.currentTypePath.Get()])
+	s.currentTypePath.Pop()
+	s.typemap = s.currentApp().Types[s.currentTypePath.Get()].GetTuple().GetAttrDefs()
 }
 
 // EnterField is called when production field is entered.
@@ -539,7 +545,7 @@ func (s *TreeShapeListener) EnterField(ctx *parser.FieldContext) {
 	type1, has := s.typemap[fieldName]
 	if has {
 		logrus.Warnf("%s) %s.%s defined multiple times",
-			s.sc.filename, s.typename, fieldName)
+			s.sc.filename, s.currentTypePath.Get(), fieldName)
 	} else {
 		type1 = &sysl.Type{}
 		type1.Type = &sysl.Type_NoType_{
@@ -547,11 +553,7 @@ func (s *TreeShapeListener) EnterField(ctx *parser.FieldContext) {
 		}
 	}
 
-	type1.SourceContext = &sysl.SourceContext{
-		Start: &sysl.SourceContext_Location{
-			Line: int32(ctx.GetStart().GetLine()),
-		},
-	}
+	type1.SourceContext = s.sc.Get(ctx.BaseParserRuleContext)
 	if ctx.QSTRING() != nil {
 		type1.Docstring = fromQString(ctx.QSTRING().GetText())
 	}
@@ -566,7 +568,7 @@ func (s *TreeShapeListener) EnterField(ctx *parser.FieldContext) {
 		}
 	}
 	s.typemap[fieldName] = type1
-	s.app_name = []string{}
+	s.app_name.Reset()
 }
 
 // ExitField is called when production field is exited.
@@ -594,7 +596,7 @@ func (s *TreeShapeListener) ExitField(ctx *parser.FieldContext) {
 
 // EnterTable_stmts is called when production table_stmts is entered.
 func (s *TreeShapeListener) EnterTable_stmts(ctx *parser.Table_stmtsContext) {
-	type1 := s.module.Apps[s.appname].Types[s.typename]
+	type1 := s.currentApp().Types[s.currentTypePath.Get()]
 	if ctx.Annotation(0) != nil {
 		if type1.Attrs == nil {
 			type1.Attrs = map[string]*sysl.Attribute{}
@@ -607,7 +609,7 @@ func (s *TreeShapeListener) EnterTable_stmts(ctx *parser.Table_stmtsContext) {
 
 // EnterTable_def is called when production table_def is entered.
 func (s *TreeShapeListener) EnterTable_def(ctx *parser.Table_defContext) {
-	type1 := s.module.Apps[s.appname].Types[s.typename]
+	type1 := s.currentApp().Types[s.currentTypePath.Get()]
 	if attribs, ok := ctx.Attribs_or_modifiers().(*parser.Attribs_or_modifiersContext); ok {
 		type1.Attrs = makeAttributeArray(attribs)
 	}
@@ -618,20 +620,16 @@ func (s *TreeShapeListener) EnterTable_def(ctx *parser.Table_defContext) {
 
 // EnterTable is called when production table is entered.
 func (s *TreeShapeListener) EnterTable(ctx *parser.TableContext) {
-	if s.typename == "" {
-		s.typename = ctx.Name_str().GetText()
-	} else {
-		s.typename = s.typename + "." + ctx.Name_str().GetText()
-	}
+	s.currentTypePath.Push(ctx.Name_str().GetText())
 	s.typemap = map[string]*sysl.Type{}
 
-	types := s.module.Apps[s.appname].Types
+	types := s.currentApp().Types
 	if ctx.TABLE() != nil {
-		if types[s.typename].GetRelation().GetAttrDefs() != nil {
+		if types[s.currentTypePath.Get()].GetRelation().GetAttrDefs() != nil {
 			panic("not implemented yet")
 		}
 
-		types[s.typename] = &sysl.Type{
+		types[s.currentTypePath.Get()] = &sysl.Type{
 			Type: &sysl.Type_Relation_{
 				Relation: &sysl.Type_Relation{
 					AttrDefs: s.typemap,
@@ -640,7 +638,7 @@ func (s *TreeShapeListener) EnterTable(ctx *parser.TableContext) {
 		}
 	}
 	if ctx.TYPE() != nil {
-		types[s.typename] = &sysl.Type{
+		types[s.currentTypePath.Get()] = &sysl.Type{
 			Type: &sysl.Type_Tuple_{
 				Tuple: &sysl.Type_Tuple{
 					AttrDefs: s.typemap,
@@ -648,7 +646,7 @@ func (s *TreeShapeListener) EnterTable(ctx *parser.TableContext) {
 			},
 		}
 	}
-	type1 := types[s.typename]
+	type1 := types[s.currentTypePath.Get()]
 	s.pushScope(type1)
 	type1.SourceContext = s.sc.Get(ctx.BaseParserRuleContext)
 }
@@ -703,7 +701,7 @@ func fixFieldDefinitions(collection *sysl.Type) {
 // ExitTable is called when production table is exited.
 func (s *TreeShapeListener) ExitTable(ctx *parser.TableContext) {
 	// wire up primary key
-	if rel := s.module.Apps[s.appname].Types[s.typename].GetRelation(); rel != nil {
+	if rel := s.currentApp().Types[s.currentTypePath.Get()].GetRelation(); rel != nil {
 		pks := []string{}
 		for _, name := range s.fieldname {
 			f := rel.GetAttrDefs()[name]
@@ -728,16 +726,10 @@ func (s *TreeShapeListener) ExitTable(ctx *parser.TableContext) {
 	s.popScope()
 
 	// Match legacy behavior
-	fixFieldDefinitions(s.module.Apps[s.appname].Types[s.typename])
+	fixFieldDefinitions(s.currentApp().Types[s.currentTypePath.Get()])
 	// End
 
-	l := strings.LastIndex(s.typename, ".")
-	if l > 0 {
-		s.typename = s.typename[:l]
-	} else {
-		s.typename = ""
-	}
-
+	s.currentTypePath.Pop()
 	s.fieldname = []string{}
 	s.typemap = nil
 }
@@ -747,7 +739,7 @@ func (s *TreeShapeListener) applyAnnotations(
 ) {
 	// Match legacy behavior
 	// Copy the annotations from the parent (tuple or relation) to each child
-	collection := s.module.Apps[s.appname].Types[s.typename]
+	collection := s.currentApp().Types[s.currentTypePath.Get()]
 
 	for _, annotation := range annotations {
 		varname := annotation.(*parser.AnnotationContext).VAR_NAME().GetText()
@@ -763,41 +755,24 @@ func (s *TreeShapeListener) applyAnnotations(
 	}
 }
 
-func (s *TreeShapeListener) pushTypename(typename string) string {
-	if s.typename != "" {
-		s.typename += "."
-	}
-	s.typename += typename
-	return s.typename
-}
-
-func (s *TreeShapeListener) popTypename() string {
-	if lastDot := strings.LastIndex(s.typename, "."); lastDot != -1 {
-		s.typename = s.typename[:lastDot]
-	} else {
-		s.typename = ""
-	}
-	return s.typename
-}
-
 // EnterUnion is called when production union is entered.
 func (s *TreeShapeListener) EnterUnion(ctx *parser.UnionContext) {
-	s.pushTypename(ctx.Name_str().GetText())
+	s.currentTypePath.Push(ctx.Name_str().GetText())
 	s.typemap = map[string]*sysl.Type{}
 
-	types := s.module.Apps[s.appname].Types
+	types := s.currentApp().Types
 
-	if types[s.typename].GetOneOf().GetType() != nil {
+	if types[s.currentTypePath.Get()].GetOneOf().GetType() != nil {
 		panic("not implemented yet")
 	}
 
-	types[s.typename] = &sysl.Type{
+	types[s.currentTypePath.Get()] = &sysl.Type{
 		Type: &sysl.Type_OneOf_{
 			OneOf: &sysl.Type_OneOf{},
 		},
 	}
 
-	type1 := types[s.typename]
+	type1 := types[s.currentTypePath.Get()]
 	if attribs, ok := ctx.Attribs_or_modifiers().(*parser.Attribs_or_modifiersContext); ok {
 		type1.Attrs = makeAttributeArray(attribs)
 	}
@@ -815,10 +790,10 @@ func (s *TreeShapeListener) ExitUnion(ctx *parser.UnionContext) {
 	s.applyAnnotations(ctx.AllAnnotation())
 	s.popScope()
 
-	context_app_part := s.module.Apps[s.appname].Name.Part
-	context_path := strings.Split(s.typename, ".")
+	context_app_part := s.currentApp().Name.Part
+	context_path := s.currentTypePath.Parts()
 
-	oneof := s.module.Apps[s.appname].Types[s.typename].GetOneOf()
+	oneof := s.currentApp().Types[s.currentTypePath.Get()].GetOneOf()
 	for _, ref := range ctx.AllUser_defined_type() {
 		oneof.Type = append(oneof.Type, &sysl.Type{
 			Type: &sysl.Type_TypeRef{
@@ -837,81 +812,62 @@ func (s *TreeShapeListener) ExitUnion(ctx *parser.UnionContext) {
 		})
 	}
 
-	s.popTypename()
-
+	s.currentTypePath.Pop()
 	s.fieldname = []string{}
 	s.typemap = nil
 }
 
-// EnterSub_package is called when production sub_package is entered.
-func (s *TreeShapeListener) EnterSub_package(ctx *parser.Sub_packageContext) {
-	top := len(s.app_name) - 1
-	str := ctx.NAME_SEP().GetText()
-	sp := strings.Split(str, "::")
-	s.app_name[top] += sp[0]
-}
-
-// ExitSub_package is called when production sub_package is exited.
-func (s *TreeShapeListener) ExitSub_package(ctx *parser.Sub_packageContext) {
-	top := len(s.app_name) - 1
-	str := ctx.NAME_SEP().GetText()
-	sp := strings.Split(str, "::")
-	s.app_name[top] = sp[1] + s.app_name[top]
-}
-
 // EnterApp_name is called when production app_name is entered.
 func (s *TreeShapeListener) EnterApp_name(*parser.App_nameContext) {
-	s.app_name = []string{}
+	s.app_name.Reset()
 }
 
 // EnterName_with_attribs is called when production name_with_attribs is entered.
 func (s *TreeShapeListener) EnterName_with_attribs(ctx *parser.Name_with_attribsContext) {
-	s.appname = ctx.App_name().GetText()
-	if _, has := s.module.Apps[s.appname]; !has {
-		s.module.Apps[s.appname] = &sysl.Application{
+	appName := ctx.App_name().GetText()
+	if _, has := s.module.Apps[appName]; !has {
+		s.module.Apps[appName] = &sysl.Application{
 			Name: &sysl.AppName{},
 		}
 	}
+	s.app = s.module.Apps[appName]
 
 	if ctx.QSTRING() != nil {
-		s.module.Apps[s.appname].LongName = fromQString(ctx.QSTRING().GetText())
+		s.currentApp().LongName = fromQString(ctx.QSTRING().GetText())
 	}
 
 	if attribs, ok := ctx.Attribs_or_modifiers().(*parser.Attribs_or_modifiersContext); ok {
 		attrs := makeAttributeArray(attribs)
-		if s.module.Apps[s.appname].Attrs == nil {
-			s.module.Apps[s.appname].Attrs = attrs
+		if s.currentApp().Attrs == nil {
+			s.currentApp().Attrs = attrs
 		} else {
-			mergeAttrs(attrs, s.module.Apps[s.appname].Attrs)
+			mergeAttrs(attrs, s.currentApp().Attrs)
 		}
 	}
 	sc := s.sc.Get(ctx.BaseParserRuleContext)
 	sc.Start.Col += 1
-	s.module.Apps[s.appname].SourceContext = sc
+	s.currentApp().SourceContext = sc
 }
 
 // ExitName_with_attribs is called when production name_with_attribs is exited.
 func (s *TreeShapeListener) ExitName_with_attribs(*parser.Name_with_attribsContext) {
-	for i := range s.app_name {
-		s.app_name[i] = strings.TrimSpace(s.app_name[i])
-	}
-	s.module.Apps[s.appname].GetName().Part = s.app_name
+	s.currentApp().Name.Part = s.app_name.Parts()
 }
 
 // EnterModel_name is called when production model_name is entered.
 func (s *TreeShapeListener) EnterModel_name(ctx *parser.Model_nameContext) {
-	if s.module.Apps[s.appname].Wrapped.Name != nil {
+	if s.currentApp().Wrapped.Name != nil {
 		panic("not implemented yet?")
 	}
 
-	s.module.Apps[s.appname].Wrapped.Name = &sysl.AppName{
+	s.currentApp().Wrapped.Name = &sysl.AppName{
 		Part: []string{ctx.Name().GetText()},
 	}
 }
 
 // EnterTable_refs is called when production table_refs is entered.
 func (s *TreeShapeListener) EnterTable_refs(ctx *parser.Table_refsContext) {
-	s.module.Apps[s.appname].Wrapped.Types[ctx.Name().GetText()] = &sysl.Type{}
+	s.currentApp().Wrapped.Types[ctx.Name().GetText()] = &sysl.Type{}
 }
 
 // EnterQuery_var is called when production query_var is entered.
@@ -928,7 +884,7 @@ func (s *TreeShapeListener) EnterQuery_var(ctx *parser.Query_varContext) {
 				TypeRef: &sysl.ScopedRef{
 					Context: &sysl.Scope{
 						Appname: &sysl.AppName{
-							Part: s.module.Apps[s.appname].Name.Part,
+							Part: s.currentApp().Name.Part,
 						},
 					},
 					Ref: &sysl.Scope{
@@ -958,11 +914,7 @@ func (s *TreeShapeListener) EnterQuery_var(ctx *parser.Query_varContext) {
 		rest_param.Type.Opt = true
 	}
 
-	rest_param.Type.SourceContext = &sysl.SourceContext{
-		Start: &sysl.SourceContext_Location{
-			Line: int32(ctx.GetStart().GetLine()),
-		},
-	}
+	rest_param.Type.SourceContext = s.sc.Get(ctx.BaseParserRuleContext)
 	s.method_urlparams = append(s.method_urlparams, rest_param)
 }
 
@@ -991,7 +943,7 @@ func (s *TreeShapeListener) EnterHttp_path_var_with_type(ctx *parser.Http_path_v
 				TypeRef: &sysl.ScopedRef{
 					Context: &sysl.Scope{
 						Appname: &sysl.AppName{
-							Part: s.module.Apps[s.appname].Name.Part,
+							Part: s.currentApp().Name.Part,
 						},
 					},
 					Ref: &sysl.Scope{
@@ -1006,14 +958,10 @@ func (s *TreeShapeListener) EnterHttp_path_var_with_type(ctx *parser.Http_path_v
 		Type: type1,
 	}
 
-	rest_param.Type.SourceContext = &sysl.SourceContext{
-		Start: &sysl.SourceContext_Location{
-			Line: int32(ctx.GetStart().GetLine()),
-		},
-	}
+	rest_param.Type.SourceContext = s.sc.Get(ctx.BaseParserRuleContext)
 
 	s.rest_urlparams = append(s.rest_urlparams, rest_param)
-	s.typename += ctx.CURLY_OPEN().GetText() + var_name + ctx.CURLY_CLOSE().GetText()
+	s.endpointName += ctx.CURLY_OPEN().GetText() + var_name + ctx.CURLY_CLOSE().GetText()
 }
 
 // ExitHttp_path_var_with_type is called when production http_path_var_with_type is exited.
@@ -1028,27 +976,27 @@ func (s *TreeShapeListener) ExitHttp_path_var_with_type(ctx *parser.Http_path_va
 
 // EnterHttp_path_static is called when production http_path_static is entered.
 func (s *TreeShapeListener) EnterHttp_path_static(ctx *parser.Http_path_staticContext) {
-	s.typename += ctx.GetText()
+	s.endpointName += ctx.GetText()
 }
 
 // EnterHttp_path_suffix is called when production http_path_suffix is entered.
 func (s *TreeShapeListener) EnterHttp_path_suffix(ctx *parser.Http_path_suffixContext) {
-	s.typename += ctx.FORWARD_SLASH().GetText()
+	s.endpointName += ctx.FORWARD_SLASH().GetText()
 }
 
 // EnterHttp_path is called when production http_path is entered.
 func (s *TreeShapeListener) EnterHttp_path(ctx *parser.Http_pathContext) {
-	s.typename = ""
+	s.endpointName = ""
 	if ctx.FORWARD_SLASH() != nil {
-		s.typename = ctx.GetText()
+		s.endpointName = ctx.GetText()
 	}
 }
 
 // ExitHttp_path is called when production http_path is exited.
 func (s *TreeShapeListener) ExitHttp_path(*parser.Http_pathContext) {
-	// s.typename is built along as we enter http_path/http_path_suffix/http_path_var_with_type
-	// commit this value to url_prefix
-	s.url_prefix = append(s.url_prefix, s.typename)
+	// s.endpointName is built along as we enter http_path/http_path_suffix/http_path_var_with_type
+	// commit this value to urlPrefixes
+	s.urlPrefixes.Push(s.endpointName)
 }
 
 // EnterRet_stmt is called when production ret_stmt is entered.
@@ -1064,16 +1012,13 @@ func (s *TreeShapeListener) EnterRet_stmt(ctx *parser.Ret_stmtContext) {
 
 // EnterTarget is called when production target is entered.
 func (s *TreeShapeListener) EnterTarget(*parser.TargetContext) {
-	s.app_name = []string{s.appname}
+	s.app_name.Reset()
 }
 
 // ExitTarget is called when production target is exited.
 func (s *TreeShapeListener) ExitTarget(*parser.TargetContext) {
-	for i := range s.app_name {
-		s.app_name[i] = strings.TrimSpace(s.app_name[i])
-	}
-	s.lastStatement().GetCall().Target.Part = s.app_name
-	s.app_name = []string{}
+	s.lastStatement().GetCall().Target.Part = s.app_name.Parts()
+	s.app_name.Reset()
 }
 
 // EnterCall_arg is called when production call_arg is entered.
@@ -1088,7 +1033,7 @@ func (s *TreeShapeListener) EnterCall_arg(ctx *parser.Call_argContext) {
 func (s *TreeShapeListener) EnterCall_stmt(ctx *parser.Call_stmtContext) {
 	appName := &sysl.AppName{}
 	if ctx.DOT_ARROW() != nil {
-		appName.Part = s.module.Apps[s.appname].Name.Part
+		appName.Part = s.currentApp().Name.Part
 	}
 	s.addToCurrentScope(&sysl.Statement{
 		Stmt: &sysl.Statement_Call{
@@ -1290,7 +1235,7 @@ func (s *TreeShapeListener) EnterText_stmt(ctx *parser.Text_stmtContext) {
 	} else {
 		s.pendingDocString = true
 
-		if s.module.Apps[s.appname].Endpoints[s.typename].GetRestParams() != nil {
+		if s.currentApp().Endpoints[s.endpointName].GetRestParams() != nil {
 			if x := s.peekScope().(*sysl.Endpoint); x != nil && len(x.Stmt) == 0 {
 				return
 			}
@@ -1315,16 +1260,16 @@ func (s *TreeShapeListener) EnterText_stmt(ctx *parser.Text_stmtContext) {
 
 // EnterMixin is called when production mixin is entered.
 func (s *TreeShapeListener) EnterMixin(*parser.MixinContext) {
-	if s.module.Apps[s.appname].Mixin2 == nil {
-		s.module.Apps[s.appname].Mixin2 = []*sysl.Application{}
+	if s.currentApp().Mixin2 == nil {
+		s.currentApp().Mixin2 = []*sysl.Application{}
 	}
 }
 
 // ExitMixin is called when production mixin is exited.
 func (s *TreeShapeListener) ExitMixin(*parser.MixinContext) {
-	s.module.Apps[s.appname].Mixin2 = append(s.module.Apps[s.appname].Mixin2, &sysl.Application{
+	s.currentApp().Mixin2 = append(s.currentApp().Mixin2, &sysl.Application{
 		Name: &sysl.AppName{
-			Part: s.app_name,
+			Part: s.app_name.Parts(),
 		},
 	})
 }
@@ -1336,7 +1281,7 @@ func (s *TreeShapeListener) EnterParam(ctx *parser.ParamContext) {
 		type1 := &sysl.Type{}
 		s.typemap[s.fieldname[len(s.fieldname)-1]] = type1
 	}
-	s.app_name = []string{}
+	s.app_name.Reset()
 }
 
 // ExitParam is called when production param is exited.
@@ -1398,7 +1343,7 @@ func (s *TreeShapeListener) ExitParams(*parser.ParamsContext) {
 		}
 		params = append(params, &p)
 	}
-	ep := s.module.Apps[s.appname].Endpoints[s.typename]
+	ep := s.currentApp().Endpoints[s.endpointName]
 	if len(params) > 0 {
 		if ep.Param == nil {
 			ep.Param = params
@@ -1418,14 +1363,6 @@ func (s *TreeShapeListener) ExitStatements(ctx *parser.StatementsContext) {
 	}
 }
 
-func (s *TreeShapeListener) urlString() string {
-	var url string
-	for _, str := range s.url_prefix {
-		url += str
-	}
-	return url
-}
-
 func (s *TreeShapeListener) PushExpr(expr *sysl.Expr) {
 	s.expr_stack = append(s.expr_stack, expr)
 }
@@ -1555,13 +1492,13 @@ func mergeAttrs(src map[string]*sysl.Attribute, dst map[string]*sysl.Attribute)
 
 // EnterMethod_def is called when production method_def is entered.
 func (s *TreeShapeListener) EnterMethod_def(ctx *parser.Method_defContext) {
-	url := s.urlString()
+	url := s.urlPrefixes.Get()
 	method := strings.TrimSpace(ctx.HTTP_VERBS().GetText())
-	s.typename = method + " " + url
+	s.endpointName = method + " " + url
 	s.method_urlparams = []*sysl.Endpoint_RestParams_QueryParam{}
-	if _, has := s.module.Apps[s.appname].Endpoints[s.typename]; !has {
-		s.module.Apps[s.appname].Endpoints[s.typename] = &sysl.Endpoint{
-			Name: s.typename,
+	if _, has := s.currentApp().Endpoints[s.endpointName]; !has {
+		s.currentApp().Endpoints[s.endpointName] = &sysl.Endpoint{
+			Name: s.endpointName,
 			RestParams: &sysl.Endpoint_RestParams{
 				Method: sysl.Endpoint_RestParams_Method(sysl.Endpoint_RestParams_Method_value[method]),
 				Path:   url,
@@ -1569,7 +1506,7 @@ func (s *TreeShapeListener) EnterMethod_def(ctx *parser.Method_defContext) {
 			Stmt: []*sysl.Statement{},
 		}
 	}
-	restEndpoint := s.module.Apps[s.appname].Endpoints[s.typename]
+	restEndpoint := s.currentApp().Endpoints[s.endpointName]
 	s.pushScope(restEndpoint)
 
 	attrs := map[string]*sysl.Attribute{
@@ -1608,12 +1545,8 @@ func (s *TreeShapeListener) EnterMethod_def(ctx *parser.Method_defContext) {
 			qcopy := &sysl.Endpoint_RestParams_QueryParam{
 				Name: q.Name,
 				Type: &sysl.Type{
-					Type: q.Type.Type,
-					SourceContext: &sysl.SourceContext{
-						Start: &sysl.SourceContext_Location{
-							Line: int32(ctx.GetStart().GetLine()),
-						},
-					},
+					Type:          q.Type.Type,
+					SourceContext: s.sc.Get(ctx.BaseParserRuleContext),
 				},
 			}
 			qparams = append(qparams, qcopy)
@@ -1634,46 +1567,46 @@ func (s *TreeShapeListener) EnterMethod_def(ctx *parser.Method_defContext) {
 // ExitMethod_def is called when production method_def is exited.
 func (s *TreeShapeListener) ExitMethod_def(*parser.Method_defContext) {
 	if len(s.method_urlparams) > 0 {
-		qparams := s.module.Apps[s.appname].Endpoints[s.typename].RestParams.QueryParam
+		qparams := s.currentApp().Endpoints[s.endpointName].RestParams.QueryParam
 		if qparams == nil {
 			qparams = []*sysl.Endpoint_RestParams_QueryParam{}
 		}
 		qparams = append(qparams, s.method_urlparams...)
-		s.module.Apps[s.appname].Endpoints[s.typename].RestParams.QueryParam = qparams
+		s.currentApp().Endpoints[s.endpointName].RestParams.QueryParam = qparams
 	}
-	if s.module.Apps[s.appname].Endpoints[s.typename].Param != nil {
-		for i, p := range s.module.Apps[s.appname].Endpoints[s.typename].Param {
+	if s.currentApp().Endpoints[s.endpointName].Param != nil {
+		for i, p := range s.currentApp().Endpoints[s.endpointName].Param {
 			if p.GetType().GetNoType() != nil {
-				s.module.Apps[s.appname].Endpoints[s.typename].Param[i] = &sysl.Param{}
+				s.currentApp().Endpoints[s.endpointName].Param[i] = &sysl.Param{}
 			}
 		}
 	}
 
-	if len(s.module.Apps[s.appname].Endpoints[s.typename].Stmt) == 0 {
-		s.module.Apps[s.appname].Endpoints[s.typename].Stmt = nil
+	if len(s.currentApp().Endpoints[s.endpointName].Stmt) == 0 {
+		s.currentApp().Endpoints[s.endpointName].Stmt = nil
 	}
 
 	s.popScope()
-	s.typename = ""
+	s.endpointName = ""
 	s.http_path_query_param = ""
 }
 
 // EnterSimple_endpoint is called when production api_endpoint is entered.
 func (s *TreeShapeListener) EnterSimple_endpoint(ctx *parser.Simple_endpointContext) {
 	if ctx.WHATEVER() != nil {
-		s.module.Apps[s.appname].Endpoints[ctx.WHATEVER().GetText()] = &sysl.Endpoint{
+		s.currentApp().Endpoints[ctx.WHATEVER().GetText()] = &sysl.Endpoint{
 			Name: ctx.WHATEVER().GetText(),
 		}
 		return
 	}
-	s.typename = ctx.Endpoint_name().GetText()
-	ep := s.module.Apps[s.appname].Endpoints[s.typename]
+	s.endpointName = ctx.Endpoint_name().GetText()
+	ep := s.currentApp().Endpoints[s.endpointName]
 
 	if ep == nil {
 		ep = &sysl.Endpoint{
-			Name: s.typename,
+			Name: s.endpointName,
 		}
-		s.module.Apps[s.appname].Endpoints[s.typename] = ep
+		s.currentApp().Endpoints[s.endpointName] = ep
 	}
 
 	if ctx.QSTRING() != nil {
@@ -1697,7 +1630,7 @@ func (s *TreeShapeListener) EnterSimple_endpoint(ctx *parser.Simple_endpointCont
 			ep.Stmt = []*sysl.Statement{}
 		}
 
-		s.pushScope(s.module.Apps[s.appname].Endpoints[s.typename])
+		s.pushScope(s.currentApp().Endpoints[s.endpointName])
 	}
 	ep.SourceContext = s.sc.Get(ctx.BaseParserRuleContext)
 }
@@ -1707,11 +1640,11 @@ func (s *TreeShapeListener) ExitSimple_endpoint(ctx *parser.Simple_endpointConte
 	if ctx.Statements(0) != nil {
 		s.popScope()
 	}
-	ep := s.module.Apps[s.appname].Endpoints[s.typename]
+	ep := s.currentApp().Endpoints[s.endpointName]
 	if ep != nil && len(ep.Attrs) == 0 {
 		ep.Attrs = nil
 	}
-	s.typename = ""
+	s.endpointName = ""
 }
 
 // EnterRest_endpoint is called when production rest_endpoint is entered.
@@ -1728,7 +1661,7 @@ func (s *TreeShapeListener) EnterRest_endpoint(ctx *parser.Rest_endpointContext)
 
 // ExitRest_endpoint is called when production rest_endpoint is exited.
 func (s *TreeShapeListener) ExitRest_endpoint(*parser.Rest_endpointContext) {
-	s.url_prefix = s.url_prefix[:len(s.url_prefix)-1]
+	s.urlPrefixes.Pop()
 	ltop := len(s.rest_urlparams_len) - 1
 	if ltop >= 0 {
 		l := s.rest_urlparams_len[ltop]
@@ -1737,7 +1670,7 @@ func (s *TreeShapeListener) ExitRest_endpoint(*parser.Rest_endpointContext) {
 	}
 	s.rest_attrs = s.rest_attrs[:len(s.rest_attrs)-1]
 
-	if len(s.url_prefix) != len(s.rest_attrs) {
+	if len(s.urlPrefixes.parts) != len(s.rest_attrs) {
 		panic("something is wrong")
 	}
 }
@@ -1745,7 +1678,7 @@ func (s *TreeShapeListener) ExitRest_endpoint(*parser.Rest_endpointContext) {
 // EnterCollector_call_stmt is called when production collector_call_stmt is entered.
 func (s *TreeShapeListener) EnterCollector_call_stmt(ctx *parser.Collector_call_stmtContext) {
 	appName := &sysl.AppName{}
-	s.app_name = []string{}
+	s.app_name.Reset()
 	s.addToCurrentScope(&sysl.Statement{
 		Stmt: &sysl.Statement_Call{
 			Call: &sysl.Call{
@@ -1771,18 +1704,14 @@ func (s *TreeShapeListener) EnterCollector_http_stmt(ctx *parser.Collector_http_
 
 // ExitSubscriber is called when production subscriber is exited.
 func (s *TreeShapeListener) ExitSubscriber(*parser.SubscriberContext) {
-	for i := range s.app_name {
-		s.app_name[i] = strings.TrimSpace(s.app_name[i])
-	}
-
-	s.lastStatement().GetCall().Target.Part = s.app_name
-	s.app_name = []string{}
+	s.lastStatement().GetCall().Target.Part = s.app_name.Parts()
+	s.app_name.Reset()
 }
 
 // EnterCollector_pubsub_call is called when production collector_pubsub_call is entered.
 func (s *TreeShapeListener) EnterCollector_pubsub_call(ctx *parser.Collector_pubsub_callContext) {
 	appName := &sysl.AppName{}
-	s.app_name = []string{}
+	s.app_name.Reset()
 	publisher := ctx.Publisher().GetText() + ctx.ARROW_RIGHT().GetText()
 	s.addToCurrentScope(&sysl.Statement{
 		Stmt: &sysl.Statement_Call{
@@ -1816,14 +1745,14 @@ func (s *TreeShapeListener) ExitCollector_stmts(ctx *parser.Collector_stmtsConte
 
 // EnterCollector is called when production collector is entered.
 func (s *TreeShapeListener) EnterCollector(ctx *parser.CollectorContext) {
-	s.typename = ctx.COLLECTOR().GetText()
-	ep := s.module.Apps[s.appname].Endpoints[s.typename]
+	collector := ctx.COLLECTOR().GetText()
+	ep := s.currentApp().Endpoints[collector]
 
 	if ep == nil {
 		ep = &sysl.Endpoint{
-			Name: s.typename,
+			Name: collector,
 		}
-		s.module.Apps[s.appname].Endpoints[s.typename] = ep
+		s.currentApp().Endpoints[collector] = ep
 	}
 
 	if ctx.Collector_stmts(0) != nil {
@@ -1838,29 +1767,29 @@ func (s *TreeShapeListener) EnterCollector(ctx *parser.CollectorContext) {
 
 // ExitCollector is called when production collector is exited.
 func (s *TreeShapeListener) ExitCollector(ctx *parser.CollectorContext) {
+	collector := ctx.COLLECTOR().GetText()
 	if ctx.Collector_stmts(0) != nil {
 		s.popScope()
 	}
-	ep := s.module.Apps[s.appname].Endpoints[s.typename]
+	ep := s.currentApp().Endpoints[collector]
 	if len(ep.Attrs) == 0 {
 		ep.Attrs = nil
 	}
-	s.typename = ""
 }
 
 // EnterEvent is called when production event is entered.
 func (s *TreeShapeListener) EnterEvent(ctx *parser.EventContext) {
 	if ctx.Name_str() != nil {
-		s.typename = ctx.Name_str().GetText()
-		// fmt.Printf("Event: %s\n", s.typename)
-		ep := s.module.Apps[s.appname].Endpoints[s.typename]
+		s.endpointName = ctx.Name_str().GetText()
+		// fmt.Printf("Event: %s\n", s.endpointName)
+		ep := s.currentApp().Endpoints[s.endpointName]
 		if ep == nil {
 			ep = &sysl.Endpoint{
-				Name:          s.typename,
+				Name:          s.endpointName,
 				IsPubsub:      true,
 				SourceContext: s.sc.Get(ctx.BaseParserRuleContext),
 			}
-			s.module.Apps[s.appname].Endpoints[s.typename] = ep
+			s.currentApp().Endpoints[s.endpointName] = ep
 		}
 		if ctx.Attribs_or_modifiers() != nil {
 			ep.Attrs = makeAttributeArray(ctx.Attribs_or_modifiers().(*parser.Attribs_or_modifiersContext))
@@ -1879,15 +1808,15 @@ func (s *TreeShapeListener) ExitEvent(ctx *parser.EventContext) {
 	if ctx.Statements(0) != nil {
 		s.popScope()
 	}
-	s.typename = ""
+	s.endpointName = ""
 }
 
 // EnterSubscribe is called when production subscribe is entered.
 func (s *TreeShapeListener) EnterSubscribe(ctx *parser.SubscribeContext) {
 	if ctx.App_name() != nil {
 		eventName := ctx.Name_str().GetText()
-		s.typename = ctx.App_name().GetText() + ctx.ARROW_RIGHT().GetText() + eventName
-		// fmt.Printf("\t%s Subscriber: %s\n", s.appname, s.typename)
+		s.endpointName = ctx.App_name().GetText() + ctx.ARROW_RIGHT().GetText() + eventName
+		// fmt.Printf("\t%s Subscriber: %s\n", s.appName, s.endpointName)
 		str := strings.Split(ctx.App_name().GetText(), "::")
 		for i := range str {
 			str[i] = strings.TrimSpace(str[i])
@@ -1896,7 +1825,7 @@ func (s *TreeShapeListener) EnterSubscribe(ctx *parser.SubscribeContext) {
 			Part: str,
 		}
 		typeEndpoint := &sysl.Endpoint{
-			Name:          s.typename,
+			Name:          s.endpointName,
 			Source:        app_src,
 			SourceContext: s.sc.Get(ctx.BaseParserRuleContext),
 		}
@@ -1907,7 +1836,7 @@ func (s *TreeShapeListener) EnterSubscribe(ctx *parser.SubscribeContext) {
 			typeEndpoint.Stmt = []*sysl.Statement{}
 			s.pushScope(typeEndpoint)
 		}
-		s.module.Apps[s.appname].Endpoints[s.typename] = typeEndpoint
+		s.currentApp().Endpoints[s.endpointName] = typeEndpoint
 		srcAppName := syslutil.GetAppName(app_src)
 		srcApp := syslutil.GetApp(app_src, s.module)
 		if srcApp == nil {
@@ -1932,8 +1861,8 @@ func (s *TreeShapeListener) EnterSubscribe(ctx *parser.SubscribeContext) {
 		stmt := &sysl.Statement{
 			Stmt: &sysl.Statement_Call{
 				Call: &sysl.Call{
-					Target:   s.module.Apps[s.appname].Name,
-					Endpoint: s.typename,
+					Target:   s.currentApp().Name,
+					Endpoint: s.endpointName,
 				},
 			},
 		}
@@ -1946,7 +1875,7 @@ func (s *TreeShapeListener) ExitSubscribe(ctx *parser.SubscribeContext) {
 	if ctx.Statements(0) != nil {
 		s.popScope()
 	}
-	s.typename = ""
+	s.endpointName = ""
 }
 
 // ExitView_type_spec is called when production view_type_spec is exited.
@@ -2852,7 +2781,7 @@ func (s *TreeShapeListener) ExitTransform_return_type(ctx *parser.Transform_retu
 
 // EnterView_return_type is called when production view_return_type is entered.
 func (s *TreeShapeListener) EnterView_return_type(*parser.View_return_typeContext) {
-	s.fieldname = append(s.fieldname, "view-return"+s.typename)
+	s.fieldname = append(s.fieldname, "view-return"+s.viewName)
 	s.typemap[s.fieldname[len(s.fieldname)-1]] = &sysl.Type{}
 }
 
@@ -2911,7 +2840,7 @@ func (s *TreeShapeListener) EnterView_param(ctx *parser.View_paramContext) {
 
 // ExitView_param is called when production view_param is exited.
 func (s *TreeShapeListener) ExitView_param(*parser.View_paramContext) {
-	view := s.module.Apps[s.appname].Views[s.typename]
+	view := s.currentApp().Views[s.viewName]
 	paramName := s.fieldname[len(s.fieldname)-1]
 	type1 := s.typemap[paramName]
 
@@ -2932,7 +2861,7 @@ func (s *TreeShapeListener) ExitView_param(*parser.View_paramContext) {
 
 // EnterView is called when production view is entered.
 func (s *TreeShapeListener) EnterView(ctx *parser.ViewContext) {
-	viewName := ctx.Name_str().GetText()
+	s.viewName = ctx.Name_str().GetText()
 
 	// There is a bug in the antlr4 go runtime that means we cant directly get the text between 2 tokens!
 	// To work around this, take the full text and the just cut it off at the expected text index
@@ -2951,24 +2880,23 @@ func (s *TreeShapeListener) EnterView(ctx *parser.ViewContext) {
 		index++
 	}
 
-	s.module.Apps[s.appname].Views[viewName] = &sysl.View{
+	s.currentApp().Views[s.viewName] = &sysl.View{
 		Param:         []*sysl.Param{},
 		RetType:       &sysl.Type{},
 		SourceContext: sc,
 	}
 	if ctx.Attribs_or_modifiers() != nil {
-		v := s.module.Apps[s.appname].Views[viewName]
+		v := s.currentApp().Views[s.viewName]
 		v.Attrs = makeAttributeArray(ctx.Attribs_or_modifiers().(*parser.Attribs_or_modifiersContext))
 	}
 
-	s.typename = viewName
 	s.fieldname = []string{}
 	s.typemap = map[string]*sysl.Type{}
 }
 
 // ExitView is called when production view is exited.
 func (s *TreeShapeListener) ExitView(ctx *parser.ViewContext) {
-	view := s.module.Apps[s.appname].Views[s.typename]
+	view := s.currentApp().Views[s.viewName]
 	if ctx.Abstract_view() == nil {
 		view.Expr = s.popExpr()
 	} else {
@@ -2989,7 +2917,7 @@ func (s *TreeShapeListener) ExitView(ctx *parser.ViewContext) {
 		}
 		view.Attrs = attributes
 	}
-	t1, has := s.typemap["view-return"+s.typename]
+	t1, has := s.typemap["view-return"+s.viewName]
 	if has {
 		view.RetType = t1
 	} else {
@@ -2997,23 +2925,18 @@ func (s *TreeShapeListener) ExitView(ctx *parser.ViewContext) {
 	}
 	s.fieldname = []string{}
 	s.typemap = map[string]*sysl.Type{}
-	s.typename = ""
 }
 
 // EnterAlias is called when production alias is entered.
 func (s *TreeShapeListener) EnterAlias(ctx *parser.AliasContext) {
-	if s.typename == "" {
-		s.typename = ctx.Name_str().GetText()
-	} else {
-		s.typename = s.typename + "." + ctx.Name_str().GetText()
-	}
+	s.currentTypePath.Push(ctx.Name_str().GetText())
 	type1 := &sysl.Type{}
 
 	s.typemap = map[string]*sysl.Type{
-		s.typename: type1,
+		s.currentTypePath.Get(): type1,
 	}
-	s.fieldname = []string{s.typename}
-	s.module.Apps[s.appname].Types[s.typename] = type1
+	s.fieldname = []string{s.currentTypePath.Get()}
+	s.currentApp().Types[s.currentTypePath.Get()] = type1
 
 	if ctx.Attribs_or_modifiers() != nil {
 		type1.Attrs = makeAttributeArray(ctx.Attribs_or_modifiers().(*parser.Attribs_or_modifiersContext))
@@ -3026,9 +2949,9 @@ func (s *TreeShapeListener) EnterAlias(ctx *parser.AliasContext) {
 
 // ExitAlias is called when production alias is exited.
 func (s *TreeShapeListener) ExitAlias(ctx *parser.AliasContext) {
-	s.module.Apps[s.appname].Types[s.typename] = s.typemap[s.fieldname[len(s.fieldname)-1]]
+	s.currentApp().Types[s.currentTypePath.Get()] = s.typemap[s.fieldname[len(s.fieldname)-1]]
 
-	s.typename = ""
+	s.currentTypePath.Pop()
 	s.fieldname = []string{}
 	s.typemap = map[string]*sysl.Type{}
 	if ctx.Annotation(0) != nil {
@@ -3038,36 +2961,35 @@ func (s *TreeShapeListener) ExitAlias(ctx *parser.AliasContext) {
 
 // EnterApp_decl is called when production app_decl is entered.
 func (s *TreeShapeListener) EnterApp_decl(ctx *parser.App_declContext) {
-	if s.module.Apps[s.appname].Types == nil && (ctx.Table(0) != nil || ctx.Alias(0) != nil) {
-		s.module.Apps[s.appname].Types = map[string]*sysl.Type{}
+	if s.currentApp().Types == nil && (ctx.Table(0) != nil || ctx.Alias(0) != nil) {
+		s.currentApp().Types = map[string]*sysl.Type{}
 	}
 	has_stmts := ctx.Simple_endpoint(0) != nil ||
 		ctx.Rest_endpoint(0) != nil ||
 		ctx.Event(0) != nil ||
 		ctx.Subscribe(0) != nil ||
 		ctx.Collector(0) != nil
-	if s.module.Apps[s.appname].Endpoints == nil && has_stmts {
-		s.module.Apps[s.appname].Endpoints = map[string]*sysl.Endpoint{}
+	if s.currentApp().Endpoints == nil && has_stmts {
+		s.currentApp().Endpoints = map[string]*sysl.Endpoint{}
 	}
-	if s.module.Apps[s.appname].Wrapped == nil && len(ctx.AllFacade()) > 0 {
-		s.module.Apps[s.appname].Wrapped = &sysl.Application{
+	if s.currentApp().Wrapped == nil && len(ctx.AllFacade()) > 0 {
+		s.currentApp().Wrapped = &sysl.Application{
 			Types: map[string]*sysl.Type{},
 		}
 	}
-	if s.module.Apps[s.appname].Views == nil && ctx.View(0) != nil {
-		s.module.Apps[s.appname].Views = map[string]*sysl.View{}
+	if s.currentApp().Views == nil && ctx.View(0) != nil {
+		s.currentApp().Views = map[string]*sysl.View{}
 	}
 	if ctx.Annotation(0) != nil {
-		if s.module.Apps[s.appname].Attrs == nil {
-			s.module.Apps[s.appname].Attrs = map[string]*sysl.Attribute{}
+		if s.currentApp().Attrs == nil {
+			s.currentApp().Attrs = map[string]*sysl.Attribute{}
 		}
-		s.pushScope(s.module.Apps[s.appname])
+		s.pushScope(s.currentApp())
 	}
 
-	s.url_prefix = []string{""}
 	s.rest_queryparams = []*sysl.Endpoint_RestParams_QueryParam{}
 	s.rest_queryparams_len = []int{0}
-	s.rest_attrs = []map[string]*sysl.Attribute{nil}
+	s.rest_attrs = []map[string]*sysl.Attribute{}
 	s.typemap = map[string]*sysl.Type{}
 }
 
@@ -3076,7 +2998,6 @@ func (s *TreeShapeListener) ExitApp_decl(ctx *parser.App_declContext) {
 	if ctx.Annotation(0) != nil {
 		s.popScope()
 	}
-	s.typename = ""
 }
 
 // EnterImport_stmt is called when production import_stmt is entered.
@@ -3112,11 +3033,6 @@ func (s *TreeShapeListener) EnterImport_stmt(ctx *parser.Import_stmtContext) {
 	s.imports = append(s.imports, id)
 }
 
-// ExitSysl_file is called when production sysl_file is exited.
-func (s *TreeShapeListener) ExitSysl_file(*parser.Sysl_fileContext) {
-	s.appname = ""
-}
-
 func (s *TreeShapeListener) currentType() *sysl.Type {
 	return s.typemap[s.fieldname[len(s.fieldname)-1]]
 }
diff --git a/pkg/parse/utils.go b/pkg/parse/utils.go
index 2c08a439..e0603baa 100644
--- a/pkg/parse/utils.go
+++ b/pkg/parse/utils.go
@@ -99,3 +99,49 @@ func primitiveFromNativeDataType(native antlr.TerminalNode) (*sysl.Type_Primitiv
 	}
 	return &sysl.Type_Primitive_{Primitive: primitiveType}, constraint
 }
+
+type PathStack struct {
+	sep   string
+	parts []string
+
+	path   string
+	prefix string
+}
+
+func NewPathStack(sep string) PathStack {
+	return PathStack{
+		sep:   sep,
+		parts: []string{},
+	}
+}
+
+func (p PathStack) Get() string {
+	return p.path
+}
+
+func (p *PathStack) Push(items ...string) string {
+	for _, i := range items {
+		p.parts = append(p.parts, strings.TrimSpace(i))
+	}
+	return p.update()
+}
+
+func (p *PathStack) Pop() string {
+	p.parts = p.parts[:len(p.parts)-1]
+	return p.update()
+}
+
+func (p *PathStack) Reset() string {
+	p.parts = []string{}
+	return p.update()
+}
+
+// Parts() clones the path items into a new slice so that it is safe to store
+func (p PathStack) Parts() []string {
+	return append([]string{}, p.parts...)
+}
+
+func (p *PathStack) update() string {
+	p.path = p.prefix + strings.Join(p.parts, p.sep)
+	return p.path
+}


Test patch:
diff --git a/pkg/parse/Parser_test.go b/pkg/parse/Parser_test.go
index 850fd52f..515343ed 100644
--- a/pkg/parse/Parser_test.go
+++ b/pkg/parse/Parser_test.go
@@ -400,12 +400,6 @@ func TestInplaceTuple(t *testing.T) {
 	testParseAgainstGolden(t, "tests/inplace_tuple.sysl", "")
 }
 
-func TestRelational(t *testing.T) {
-	t.Parallel()
-
-	testParseAgainstGolden(t, "tests/school.sysl", "")
-}
-
 func TestImports(t *testing.T) {
 	t.Parallel()
 
@@ -418,7 +412,7 @@ func TestForeignImports(t *testing.T) {
 	testParseAgainstGolden(t, "tests/foreign_import_swagger.sysl", "")
 }
 
-func TestRootArg(t *testing.T) {
+func TestRootArgAndRelational(t *testing.T) {
 	t.Parallel()
 
 	testParseAgainstGolden(t, "school.sysl", "tests")
diff --git a/pkg/parse/tests/alias.sysl.golden.textpb b/pkg/parse/tests/alias.sysl.golden.textpb
index 28fccc20..498a05be 100644
--- a/pkg/parse/tests/alias.sysl.golden.textpb
+++ b/pkg/parse/tests/alias.sysl.golden.textpb
@@ -46,8 +46,14 @@ apps: <
             value: <
               primitive: STRING
               source_context: <
+                file: "tests/alias.sysl"
                 start: <
                   line: 7
+                  col: 18
+                >
+                end: <
+                  line: 7
+                  col: 18
                 >
               >
             >
@@ -85,8 +91,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/alias.sysl"
                 start: <
                   line: 10
+                  col: 15
+                >
+                end: <
+                  line: 10
+                  col: 15
                 >
               >
             >
@@ -96,8 +108,14 @@ apps: <
             value: <
               primitive: STRING
               source_context: <
+                file: "tests/alias.sysl"
                 start: <
                   line: 11
+                  col: 18
+                >
+                end: <
+                  line: 11
+                  col: 18
                 >
               >
             >
diff --git a/pkg/parse/tests/bad_order.sysl.golden.textpb b/pkg/parse/tests/bad_order.sysl.golden.textpb
index eef8fd81..230bb48a 100644
--- a/pkg/parse/tests/bad_order.sysl.golden.textpb
+++ b/pkg/parse/tests/bad_order.sysl.golden.textpb
@@ -41,8 +41,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/bad_order.sysl"
                 start: <
                   line: 3
+                  col: 13
+                >
+                end: <
+                  line: 3
+                  col: 19
                 >
               >
             >
@@ -53,8 +59,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/bad_order.sysl"
                 start: <
                   line: 3
+                  col: 23
+                >
+                end: <
+                  line: 3
+                  col: 32
                 >
               >
             >
@@ -65,8 +77,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/bad_order.sysl"
                 start: <
                   line: 3
+                  col: 34
+                >
+                end: <
+                  line: 3
+                  col: 44
                 >
               >
             >
@@ -76,8 +94,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/bad_order.sysl"
                 start: <
                   line: 2
+                  col: 5
+                >
+                end: <
+                  line: 2
+                  col: 13
                 >
               >
             >
@@ -123,8 +147,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/bad_order.sysl"
                 start: <
                   line: 2
+                  col: 5
+                >
+                end: <
+                  line: 2
+                  col: 13
                 >
               >
             >
@@ -134,8 +164,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/bad_order.sysl"
                 start: <
                   line: 6
+                  col: 15
+                >
+                end: <
+                  line: 6
+                  col: 25
                 >
               >
             >
diff --git a/pkg/parse/tests/docstrings.sysl.golden.textpb b/pkg/parse/tests/docstrings.sysl.golden.textpb
index 25ec4595..d8303cf4 100644
--- a/pkg/parse/tests/docstrings.sysl.golden.textpb
+++ b/pkg/parse/tests/docstrings.sysl.golden.textpb
@@ -1,143 +1,155 @@
-apps {
+apps: <
   key: "Another App"
-  value {
-    name {
+  value: <
+    name: <
       part: "Another App"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "Endpoint"
-      value {
+      value: <
         name: "Endpoint"
-        attrs {
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "multi-line documentation comment use it for long comments"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "App"
-  value {
-    name {
+  value: <
+    name: <
       part: "App"
-    }
-    attrs {
+    >
+    attrs: <
       key: "description"
-      value {
+      value: <
         s: "multi-line documentation comment use it for long comments"
-      }
-    }
-    endpoints {
+      >
+    >
+    endpoints: <
       key: "..."
-      value {
+      value: <
         name: "..."
-      }
-    }
-  }
-}
-apps {
+      >
+    >
+  >
+>
+apps: <
   key: "Model"
-  value {
-    name {
+  value: <
+    name: <
       part: "Model"
-    }
-    types {
+    >
+    types: <
       key: "TableName"
-      value {
-        attrs {
+      value: <
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "multi-line documentation comment use it for long comments"
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "ModelTwo"
-  value {
-    name {
+  value: <
+    name: <
       part: "ModelTwo"
-    }
-    types {
+    >
+    types: <
       key: "TableName"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "field"
-            value {
+            value: <
               primitive: STRING
-              attrs {
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "multi-line documentation comment use it for long comments"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/docstrings.sysl"
+                start: <
                   line: 33
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 17
+                >
+                end: <
+                  line: 36
+                  col: 8
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "field2"
-            value {
+            value: <
               primitive: STRING
               docstring: "short description here"
-              source_context {
-                start {
+              source_context: <
+                file: "tests/docstrings.sysl"
+                start: <
+                  line: 36
+                  col: 18
+                >
+                end: <
                   line: 36
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 18
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Yet Another App"
-  value {
-    name {
+  value: <
+    name: <
       part: "Yet Another App"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "AnotherEndpoint"
-      value {
+      value: <
         name: "AnotherEndpoint"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "| a multi line text statement use it to well"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "another text statement"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Endpoint"
-      value {
+      value: <
         name: "Endpoint"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "a simple text statement"
-          }
-        }
-      }
-    }
-  }
-}
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/foreign_import_swagger.sysl.golden.textpb b/pkg/parse/tests/foreign_import_swagger.sysl.golden.textpb
index 5e5904ae..6454cccf 100644
--- a/pkg/parse/tests/foreign_import_swagger.sysl.golden.textpb
+++ b/pkg/parse/tests/foreign_import_swagger.sysl.golden.textpb
@@ -59,8 +59,13 @@ apps: <
               >
               opt: true
               source_context: <
+                file: "tests/foreign_import_swagger.yaml"
                 start: <
                   line: 21
+                  col: 16
+                >
+                end: <
+                  line: 22
                 >
               >
             >
@@ -127,8 +132,14 @@ apps: <
             name: "depth"
             type: <
               source_context: <
+                file: "tests/foreign_import_swagger.sysl"
                 start: <
                   line: 19
+                  col: 13
+                >
+                end: <
+                  line: 19
+                  col: 19
                 >
               >
             >
@@ -139,8 +150,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/foreign_import_swagger.sysl"
                 start: <
                   line: 19
+                  col: 29
+                >
+                end: <
+                  line: 19
+                  col: 38
                 >
               >
             >
@@ -151,8 +168,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/foreign_import_swagger.sysl"
                 start: <
                   line: 19
+                  col: 40
+                >
+                end: <
+                  line: 19
+                  col: 50
                 >
               >
             >
@@ -180,8 +203,14 @@ apps: <
               >
               opt: true
               source_context: <
+                file: "tests/foreign_import_swagger.sysl"
                 start: <
                   line: 16
+                  col: 18
+                >
+                end: <
+                  line: 16
+                  col: 24
                 >
               >
             >
diff --git a/pkg/parse/tests/inplace_tuple.sysl.golden.textpb b/pkg/parse/tests/inplace_tuple.sysl.golden.textpb
index a7703f80..b33a0a1d 100644
--- a/pkg/parse/tests/inplace_tuple.sysl.golden.textpb
+++ b/pkg/parse/tests/inplace_tuple.sysl.golden.textpb
@@ -19,8 +19,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 19
+                  col: 15
+                >
+                end: <
+                  line: 19
+                  col: 31
                 >
               >
             >
@@ -53,8 +59,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 14
+                  col: 15
+                >
+                end: <
+                  line: 14
+                  col: 31
                 >
               >
             >
@@ -71,8 +83,14 @@ apps: <
                 scale: 2
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 15
+                  col: 15
+                >
+                end: <
+                  line: 15
+                  col: 27
                 >
               >
             >
@@ -87,8 +105,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 13
+                  col: 15
+                >
+                end: <
+                  line: 13
+                  col: 25
                 >
               >
             >
@@ -121,8 +145,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 9
+                  col: 15
+                >
+                end: <
+                  line: 9
+                  col: 31
                 >
               >
             >
@@ -151,8 +181,14 @@ apps: <
                     >
                   >
                   source_context: <
+                    file: "tests/inplace_tuple.sysl"
                     start: <
                       line: 5
+                      col: 22
+                    >
+                    end: <
+                      line: 5
+                      col: 22
                     >
                   >
                 >
@@ -176,8 +212,14 @@ apps: <
                     >
                   >
                   source_context: <
+                    file: "tests/inplace_tuple.sysl"
                     start: <
                       line: 6
+                      col: 23
+                    >
+                    end: <
+                      line: 6
+                      col: 23
                     >
                   >
                 >
@@ -202,8 +244,14 @@ apps: <
                     >
                   >
                   source_context: <
+                    file: "tests/inplace_tuple.sysl"
                     start: <
                       line: 4
+                      col: 24
+                    >
+                    end: <
+                      line: 4
+                      col: 24
                     >
                   >
                 >
@@ -227,14 +275,26 @@ apps: <
                   >
                 >
                 source_context: <
+                  file: "tests/inplace_tuple.sysl"
                   start: <
                     line: 3
+                    col: 20
+                  >
+                  end: <
+                    line: 3
+                    col: 27
                   >
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 3
+                  col: 20
+                >
+                end: <
+                  line: 3
+                  col: 27
                 >
               >
             >
@@ -264,8 +324,13 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 56
+                  col: 8
+                >
+                end: <
+                  line: 67
                 >
               >
             >
@@ -279,8 +344,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 49
+                  col: 8
+                >
+                end: <
+                  line: 56
+                  col: 8
                 >
               >
             >
@@ -298,8 +369,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 58
+                  col: 12
+                >
+                end: <
+                  line: 58
+                  col: 12
                 >
               >
             >
@@ -309,8 +386,14 @@ apps: <
             value: <
               primitive: BOOL
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 59
+                  col: 26
+                >
+                end: <
+                  line: 59
+                  col: 26
                 >
               >
             >
@@ -321,8 +404,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 57
+                  col: 12
+                >
+                end: <
+                  line: 57
+                  col: 12
                 >
               >
             >
@@ -338,8 +427,14 @@ apps: <
                     >
                   >
                   source_context: <
+                    file: "tests/inplace_tuple.sysl"
                     start: <
                       line: 60
+                      col: 12
+                    >
+                    end: <
+                      line: 64
+                      col: 12
                     >
                   >
                 >
@@ -357,8 +452,13 @@ apps: <
                     >
                   >
                   source_context: <
+                    file: "tests/inplace_tuple.sysl"
                     start: <
                       line: 64
+                      col: 12
+                    >
+                    end: <
+                      line: 67
                     >
                   >
                 >
@@ -378,8 +478,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 62
+                  col: 16
+                >
+                end: <
+                  line: 62
+                  col: 16
                 >
               >
             >
@@ -390,8 +496,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 61
+                  col: 16
+                >
+                end: <
+                  line: 61
+                  col: 16
                 >
               >
             >
@@ -402,8 +514,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 63
+                  col: 16
+                >
+                end: <
+                  line: 63
+                  col: 16
                 >
               >
             >
@@ -421,8 +539,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 65
+                  col: 16
+                >
+                end: <
+                  line: 65
+                  col: 16
                 >
               >
             >
@@ -433,8 +557,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 66
+                  col: 16
+                >
+                end: <
+                  line: 66
+                  col: 16
                 >
               >
             >
@@ -452,8 +582,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 51
+                  col: 12
+                >
+                end: <
+                  line: 51
+                  col: 12
                 >
               >
             >
@@ -463,8 +599,14 @@ apps: <
             value: <
               primitive: DATE
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 53
+                  col: 23
+                >
+                end: <
+                  line: 53
+                  col: 23
                 >
               >
             >
@@ -475,8 +617,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 52
+                  col: 12
+                >
+                end: <
+                  line: 52
+                  col: 12
                 >
               >
             >
@@ -487,8 +635,14 @@ apps: <
               no_type: <
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 54
+                  col: 12
+                >
+                end: <
+                  line: 54
+                  col: 12
                 >
               >
             >
@@ -507,15 +661,21 @@ apps: <
                 >
                 ref: <
                   appname: <
-                    part: "My "
+                    part: "My"
                   >
                   path: "Tuple Model"
                   path: "TopLevelPayload"
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 50
+                  col: 20
+                >
+                end: <
+                  line: 50
+                  col: 38
                 >
               >
             >
@@ -536,15 +696,21 @@ apps: <
                     >
                     ref: <
                       appname: <
-                        part: "My "
+                        part: "My"
                       >
                       path: "Tuple Model"
                       path: "Response"
                     >
                   >
                   source_context: <
+                    file: "tests/inplace_tuple.sysl"
                     start: <
                       line: 55
+                      col: 36
+                    >
+                    end: <
+                      line: 55
+                      col: 54
                     >
                   >
                 >
@@ -568,8 +734,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 26
+                  col: 15
+                >
+                end: <
+                  line: 26
+                  col: 27
                 >
               >
             >
@@ -584,8 +756,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 27
+                  col: 15
+                >
+                end: <
+                  line: 27
+                  col: 30
                 >
               >
             >
@@ -600,8 +778,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 24
+                  col: 16
+                >
+                end: <
+                  line: 24
+                  col: 27
                 >
               >
             >
@@ -617,8 +801,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 25
+                  col: 15
+                >
+                end: <
+                  line: 25
+                  col: 31
                 >
               >
             >
@@ -639,8 +829,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 29
+                  col: 18
+                >
+                end: <
+                  line: 29
+                  col: 18
                 >
               >
             >
@@ -655,8 +851,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 23
+                  col: 18
+                >
+                end: <
+                  line: 23
+                  col: 31
                 >
               >
             >
@@ -677,8 +879,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 28
+                  col: 20
+                >
+                end: <
+                  line: 28
+                  col: 20
                 >
               >
             >
@@ -695,8 +903,14 @@ apps: <
             value: <
               primitive: XML
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 36
+                  col: 22
+                >
+                end: <
+                  line: 36
+                  col: 22
                 >
               >
             >
@@ -706,8 +920,14 @@ apps: <
             value: <
               primitive: INT
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 32
+                  col: 20
+                >
+                end: <
+                  line: 32
+                  col: 20
                 >
               >
             >
@@ -729,8 +949,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 34
+                  col: 20
+                >
+                end: <
+                  line: 34
+                  col: 34
                 >
               >
             >
@@ -744,8 +970,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 35
+                  col: 22
+                >
+                end: <
+                  line: 35
+                  col: 32
                 >
               >
             >
@@ -760,8 +992,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 33
+                  col: 21
+                >
+                end: <
+                  line: 33
+                  col: 28
                 >
               >
             >
@@ -786,7 +1024,7 @@ apps: <
                 >
                 ref: <
                   appname: <
-                    part: "My "
+                    part: "My"
                   >
                   path: "Client Model"
                   path: "Request"
@@ -794,8 +1032,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 44
+                  col: 16
+                >
+                end: <
+                  line: 44
+                  col: 45
                 >
               >
             >
@@ -810,8 +1054,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 39
+                  col: 16
+                >
+                end: <
+                  line: 39
+                  col: 26
                 >
               >
             >
@@ -827,14 +1077,26 @@ apps: <
                   >
                 >
                 source_context: <
+                  file: "tests/inplace_tuple.sysl"
                   start: <
                     line: 40
+                    col: 17
+                  >
+                  end: <
+                    line: 40
+                    col: 34
                   >
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 40
+                  col: 17
+                >
+                end: <
+                  line: 40
+                  col: 34
                 >
               >
             >
@@ -857,8 +1119,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 42
+                  col: 18
+                >
+                end: <
+                  line: 42
+                  col: 32
                 >
               >
             >
@@ -876,8 +1144,8 @@ apps: <
                 >
                 ref: <
                   appname: <
-                    part: "My "
-                    part: "    Browser "
+                    part: "My"
+                    part: "Browser"
                   >
                   path: "Client Model"
                   path: "Request"
@@ -885,8 +1153,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 43
+                  col: 18
+                >
+                end: <
+                  line: 43
+                  col: 59
                 >
               >
             >
@@ -909,14 +1183,26 @@ apps: <
                   >
                 >
                 source_context: <
+                  file: "tests/inplace_tuple.sysl"
                   start: <
                     line: 45
+                    col: 16
+                  >
+                  end: <
+                    line: 45
+                    col: 32
                   >
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 45
+                  col: 16
+                >
+                end: <
+                  line: 45
+                  col: 32
                 >
               >
             >
@@ -938,14 +1224,26 @@ apps: <
                   >
                 >
                 source_context: <
+                  file: "tests/inplace_tuple.sysl"
                   start: <
                     line: 46
+                    col: 23
+                  >
+                  end: <
+                    line: 46
+                    col: 30
                   >
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 46
+                  col: 23
+                >
+                end: <
+                  line: 46
+                  col: 30
                 >
               >
             >
@@ -967,8 +1265,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/inplace_tuple.sysl"
                 start: <
                   line: 41
+                  col: 18
+                >
+                end: <
+                  line: 41
+                  col: 27
                 >
               >
             >
diff --git a/pkg/parse/tests/library.sysl.golden.textpb b/pkg/parse/tests/library.sysl.golden.textpb
index dc7972b6..2435e834 100644
--- a/pkg/parse/tests/library.sysl.golden.textpb
+++ b/pkg/parse/tests/library.sysl.golden.textpb
@@ -1,343 +1,421 @@
-apps {
+apps: <
   key: "School"
-  value {
-    name {
+  value: <
+    name: <
       part: "School"
-    }
-    types {
+    >
+    types: <
       key: "Class"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "Id"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "patterns"
-                value {
-                  a {
-                    elt {
+                value: <
+                  a: <
+                    elt: <
                       s: "pk"
-                    }
-                    elt {
+                    >
+                    elt: <
                       s: "autoinc"
-                    }
-                  }
-                }
-              }
-              source_context {
-                start {
+                    >
+                  >
+                >
+              >
+              source_context: <
+                file: "tests/school.sysl"
+                start: <
                   line: 3
-                }
-              }
-            }
-          }
-          primary_key {
+                  col: 14
+                >
+                end: <
+                  line: 3
+                  col: 32
+                >
+              >
+            >
+          >
+          primary_key: <
             attr_name: "Id"
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "Student"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "ClassId"
-            value {
-              attrs {
-                key: "description"
-                value {
-                  s: "describe the table"
-                }
-              }
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "School"
-                  }
+                  >
                   path: "Student"
-                }
-                ref {
+                >
+                ref: <
                   path: "Class"
                   path: "Idd"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              attrs: <
+                key: "description"
+                value: <
+                  s: "describe the table"
+                >
+              >
+              source_context: <
+                file: "tests/school.sysl"
+                start: <
+                  line: 7
+                  col: 19
+                >
+                end: <
                   line: 7
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 25
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "Id"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "describe the table"
-                }
-              }
-              attrs {
+                >
+              >
+              attrs: <
                 key: "patterns"
-                value {
-                  a {
-                    elt {
+                value: <
+                  a: <
+                    elt: <
                       s: "pk"
-                    }
-                  }
-                }
-              }
-              source_context {
-                start {
+                    >
+                  >
+                >
+              >
+              source_context: <
+                file: "tests/school.sysl"
+                start: <
                   line: 6
-                }
-              }
-            }
-          }
-          primary_key {
+                  col: 14
+                >
+                end: <
+                  line: 6
+                  col: 22
+                >
+              >
+            >
+          >
+          primary_key: <
             attr_name: "Id"
-          }
-        }
-        attrs {
+          >
+        >
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "describe the table"
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "SchoolLibrary"
-  value {
-    name {
+  value: <
+    name: <
       part: "SchoolLibrary"
-    }
-    types {
+    >
+    types: <
       key: "Book"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "Author"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
+                  line: 13
+                  col: 18
+                >
+                end: <
                   line: 13
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 18
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "BookId"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "patterns"
-                value {
-                  a {
-                    elt {
+                value: <
+                  a: <
+                    elt: <
                       s: "pk"
-                    }
-                    elt {
+                    >
+                    elt: <
                       s: "autoinc"
-                    }
-                  }
-                }
-              }
-              source_context {
-                start {
+                    >
+                  >
+                >
+              >
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
                   line: 11
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 18
+                >
+                end: <
+                  line: 11
+                  col: 36
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "name"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
+                  line: 12
+                  col: 16
+                >
+                end: <
                   line: 12
-                }
-              }
-            }
-          }
-          primary_key {
+                  col: 16
+                >
+              >
+            >
+          >
+          primary_key: <
             attr_name: "BookId"
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "Borrow"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "BookId"
-            value {
-              attrs {
-                key: "patterns"
-                value {
-                  a {
-                    elt {
-                      s: "pk"
-                    }
-                  }
-                }
-              }
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "SchoolLibrary"
-                  }
+                  >
                   path: "Borrow"
-                }
-                ref {
+                >
+                ref: <
                   path: "Book"
                   path: "BookId"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              attrs: <
+                key: "patterns"
+                value: <
+                  a: <
+                    elt: <
+                      s: "pk"
+                    >
+                  >
+                >
+              >
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
+                  line: 16
+                  col: 18
+                >
+                end: <
                   line: 16
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 34
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "DueDate"
-            value {
+            value: <
               primitive: DATE
-              source_context {
-                start {
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
                   line: 17
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 19
+                >
+                end: <
+                  line: 17
+                  col: 19
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "MemberId"
-            value {
-              attrs {
-                key: "patterns"
-                value {
-                  a {
-                    elt {
-                      s: "pk"
-                    }
-                  }
-                }
-              }
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "SchoolLibrary"
-                  }
+                  >
                   path: "Borrow"
-                }
-                ref {
+                >
+                ref: <
                   path: "Member"
                   path: "MemberId"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              attrs: <
+                key: "patterns"
+                value: <
+                  a: <
+                    elt: <
+                      s: "pk"
+                    >
+                  >
+                >
+              >
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
+                  line: 15
+                  col: 20
+                >
+                end: <
                   line: 15
-                }
-              }
-            }
-          }
-          primary_key {
+                  col: 40
+                >
+              >
+            >
+          >
+          primary_key: <
             attr_name: "MemberId"
             attr_name: "BookId"
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "Member"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "MemberId"
-            value {
-              attrs {
-                key: "description"
-                value {
-                  s: "\n"
-                }
-              }
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "SchoolLibrary"
-                  }
+                  >
                   path: "Member"
-                }
-                ref {
+                >
+                ref: <
                   path: "Student"
                   path: "Id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              attrs: <
+                key: "description"
+                value: <
+                  s: "\n"
+                >
+              >
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
                   line: 6
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 20
+                >
+                end: <
+                  line: 7
+                  col: 8
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "amount"
-            value {
+            value: <
               primitive: DECIMAL
-              constraint {
-                length {
+              constraint: <
+                length: <
                   max: 14
-                }
+                >
                 precision: 14
                 scale: 2
-              }
-              source_context {
-                start {
+              >
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
                   line: 9
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 18
+                >
+                end: <
+                  line: 9
+                  col: 30
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "city"
-            value {
+            value: <
               primitive: STRING
-              constraint {
-                length {
+              constraint: <
+                length: <
                   max: 100
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
+                  line: 8
+                  col: 16
+                >
+                end: <
                   line: 8
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 26
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "name"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/library.sysl"
+                start: <
+                  line: 7
+                  col: 16
+                >
+                end: <
                   line: 7
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
+                  col: 16
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/mixin.sysl.golden.textpb b/pkg/parse/tests/mixin.sysl.golden.textpb
index f5677c09..a2cc7cd4 100644
--- a/pkg/parse/tests/mixin.sysl.golden.textpb
+++ b/pkg/parse/tests/mixin.sysl.golden.textpb
@@ -1,254 +1,272 @@
-apps {
+apps: <
   key: "API"
-  value {
-    name {
+  value: <
+    name: <
       part: "API"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "Service Call"
-      value {
+      value: <
         name: "Service Call"
-      }
-    }
-    types {
+      >
+    >
+    types: <
       key: "UberUser"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "user"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "API"
-                  }
+                  >
                   path: "UberUser"
-                }
-                ref {
+                >
+                ref: <
                   path: "User"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/mixin.sysl"
+                start: <
                   line: 19
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    types {
+                  col: 16
+                >
+                end: <
+                  line: 19
+                  col: 16
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    types: <
       key: "User"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "some description"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/mixin.sysl"
+                start: <
+                  line: 4
+                  col: 14
+                >
+                end: <
                   line: 4
-                }
-              }
-            }
-          }
-        }
-        attrs {
+                  col: 14
+                >
+              >
+            >
+          >
+        >
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "some description"
-          }
-        }
-        attrs {
+          >
+        >
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "foo"
-              }
-            }
-          }
-        }
-      }
-    }
-    mixin2 {
-      name {
-        part: "Relational Model"
-      }
-    }
-    mixin2 {
-      name {
-        part: "TransformApp"
-      }
-    }
-    views {
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "FooTransform"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
+          >
+        >
+        ret_type: <
           primitive: INT
-        }
-        expr {
-          transform {
-            arg {
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "number"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: ADD
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      literal {
+                    >
+                    rhs: <
+                      literal: <
                         i: 1
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    mixin2: <
+      name: <
+        part: "Relational Model"
+      >
+    >
+    mixin2: <
+      name: <
+        part: "TransformApp"
+      >
+    >
+  >
+>
+apps: <
   key: "Relational Model"
-  value {
-    name {
+  value: <
+    name: <
       part: "Relational Model"
-    }
-    attrs {
+    >
+    attrs: <
       key: "patterns"
-      value {
-        a {
-          elt {
+      value: <
+        a: <
+          elt: <
             s: "abstract"
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "User"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "some description"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/mixin.sysl"
+                start: <
+                  line: 4
+                  col: 14
+                >
+                end: <
                   line: 4
-                }
-              }
-            }
-          }
-        }
-        attrs {
+                  col: 14
+                >
+              >
+            >
+          >
+        >
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "some description"
-          }
-        }
-        attrs {
+          >
+        >
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "foo"
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "TransformApp"
-  value {
-    name {
+  value: <
+    name: <
       part: "TransformApp"
-    }
-    attrs {
+    >
+    attrs: <
       key: "package"
-      value {
+      value: <
         s: "com.foo.example"
-      }
-    }
-    attrs {
+      >
+    >
+    attrs: <
       key: "patterns"
-      value {
-        a {
-          elt {
+      value: <
+        a: <
+          elt: <
             s: "abstract"
-          }
-        }
-      }
-    }
-    views {
+          >
+        >
+      >
+    >
+    views: <
       key: "FooTransform"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
+          >
+        >
+        ret_type: <
           primitive: INT
-        }
-        expr {
-          transform {
-            arg {
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "number"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: ADD
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      literal {
+                    >
+                    rhs: <
+                      literal: <
                         i: 1
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/petshop.sysl.golden.textpb b/pkg/parse/tests/petshop.sysl.golden.textpb
index 74831298..43c552b6 100644
--- a/pkg/parse/tests/petshop.sysl.golden.textpb
+++ b/pkg/parse/tests/petshop.sysl.golden.textpb
@@ -45,8 +45,14 @@ apps: <
               primitive: DECIMAL
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 56
+                  col: 23
+                >
+                end: <
+                  line: 56
+                  col: 30
                 >
               >
             >
@@ -66,8 +72,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 57
+                  col: 17
+                >
+                end: <
+                  line: 57
+                  col: 36
                 >
               >
             >
@@ -78,8 +90,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 53
+                  col: 16
+                >
+                end: <
+                  line: 53
+                  col: 22
                 >
               >
             >
@@ -100,14 +118,26 @@ apps: <
                   >
                 >
                 source_context: <
+                  file: "tests/petshop.sysl"
                   start: <
                     line: 55
+                    col: 16
+                  >
+                  end: <
+                    line: 55
+                    col: 23
                   >
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 55
+                  col: 16
+                >
+                end: <
+                  line: 55
+                  col: 23
                 >
               >
             >
@@ -118,8 +148,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 54
+                  col: 19
+                >
+                end: <
+                  line: 54
+                  col: 25
                 >
               >
             >
@@ -137,8 +173,14 @@ apps: <
               primitive: DATE
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 49
+                  col: 15
+                >
+                end: <
+                  line: 49
+                  col: 19
                 >
               >
             >
@@ -158,8 +200,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 50
+                  col: 17
+                >
+                end: <
+                  line: 50
+                  col: 36
                 >
               >
             >
@@ -170,8 +218,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 48
+                  col: 16
+                >
+                end: <
+                  line: 48
+                  col: 22
                 >
               >
             >
@@ -189,8 +243,14 @@ apps: <
               primitive: DATE
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 61
+                  col: 15
+                >
+                end: <
+                  line: 61
+                  col: 19
                 >
               >
             >
@@ -200,8 +260,14 @@ apps: <
             value: <
               primitive: INT
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 63
+                  col: 19
+                >
+                end: <
+                  line: 63
+                  col: 19
                 >
               >
             >
@@ -212,8 +278,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 60
+                  col: 16
+                >
+                end: <
+                  line: 60
+                  col: 22
                 >
               >
             >
@@ -224,8 +296,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 62
+                  col: 19
+                >
+                end: <
+                  line: 62
+                  col: 22
                 >
               >
             >
@@ -253,14 +331,26 @@ apps: <
                   >
                 >
                 source_context: <
+                  file: "tests/petshop.sysl"
                   start: <
                     line: 44
+                    col: 18
+                  >
+                  end: <
+                    line: 44
+                    col: 25
                   >
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 44
+                  col: 18
+                >
+                end: <
+                  line: 44
+                  col: 25
                 >
               >
             >
@@ -281,14 +371,26 @@ apps: <
                   >
                 >
                 source_context: <
+                  file: "tests/petshop.sysl"
                   start: <
                     line: 43
+                    col: 21
+                  >
+                  end: <
+                    line: 43
+                    col: 28
                   >
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 43
+                  col: 21
+                >
+                end: <
+                  line: 43
+                  col: 28
                 >
               >
             >
@@ -299,8 +401,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 45
+                  col: 19
+                >
+                end: <
+                  line: 45
+                  col: 22
                 >
               >
             >
@@ -1063,8 +1171,14 @@ apps: <
               >
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 13
+                  col: 23
+                >
+                end: <
+                  line: 13
+                  col: 36
                 >
               >
             >
@@ -1080,8 +1194,14 @@ apps: <
               >
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 14
+                  col: 21
+                >
+                end: <
+                  line: 14
+                  col: 32
                 >
               >
             >
@@ -1104,8 +1224,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 9
+                  col: 19
+                >
+                end: <
+                  line: 9
+                  col: 37
                 >
               >
             >
@@ -1116,8 +1242,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 10
+                  col: 21
+                >
+                end: <
+                  line: 10
+                  col: 27
                 >
               >
             >
@@ -1128,8 +1260,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 15
+                  col: 19
+                >
+                end: <
+                  line: 15
+                  col: 22
                 >
               >
             >
@@ -1140,8 +1278,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 12
+                  col: 19
+                >
+                end: <
+                  line: 12
+                  col: 22
                 >
               >
             >
@@ -1152,8 +1296,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 11
+                  col: 19
+                >
+                end: <
+                  line: 11
+                  col: 25
                 >
               >
             >
@@ -1174,8 +1324,14 @@ apps: <
               primitive: DATE
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 5
+                  col: 15
+                >
+                end: <
+                  line: 5
+                  col: 19
                 >
               >
             >
@@ -1198,8 +1354,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 3
+                  col: 22
+                >
+                end: <
+                  line: 3
+                  col: 40
                 >
               >
             >
@@ -1209,8 +1371,14 @@ apps: <
             value: <
               primitive: INT
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 6
+                  col: 17
+                >
+                end: <
+                  line: 6
+                  col: 17
                 >
               >
             >
@@ -1221,8 +1389,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 4
+                  col: 16
+                >
+                end: <
+                  line: 4
+                  col: 22
                 >
               >
             >
@@ -1263,8 +1437,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 25
+                  col: 22
+                >
+                end: <
+                  line: 25
+                  col: 46
                 >
               >
             >
@@ -1295,8 +1475,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 26
+                  col: 17
+                >
+                end: <
+                  line: 26
+                  col: 31
                 >
               >
             >
@@ -1328,8 +1514,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 19
+                  col: 19
+                >
+                end: <
+                  line: 19
+                  col: 25
                 >
               >
             >
@@ -1340,8 +1532,14 @@ apps: <
               primitive: DATE
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 21
+                  col: 15
+                >
+                end: <
+                  line: 21
+                  col: 19
                 >
               >
             >
@@ -1352,8 +1550,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 20
+                  col: 16
+                >
+                end: <
+                  line: 20
+                  col: 22
                 >
               >
             >
@@ -1364,8 +1568,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 22
+                  col: 19
+                >
+                end: <
+                  line: 22
+                  col: 22
                 >
               >
             >
@@ -1388,8 +1598,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 18
+                  col: 17
+                >
+                end: <
+                  line: 18
+                  col: 35
                 >
               >
             >
@@ -1423,8 +1639,14 @@ apps: <
             value: <
               primitive: INT
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 117
+                  col: 19
+                >
+                end: <
+                  line: 117
+                  col: 19
                 >
               >
             >
@@ -1435,8 +1657,14 @@ apps: <
               primitive: DATE
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 119
+                  col: 15
+                >
+                end: <
+                  line: 119
+                  col: 19
                 >
               >
             >
@@ -1447,8 +1675,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 121
+                  col: 19
+                >
+                end: <
+                  line: 121
+                  col: 22
                 >
               >
             >
@@ -1459,8 +1693,14 @@ apps: <
               primitive: STRING
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 118
+                  col: 16
+                >
+                end: <
+                  line: 118
+                  col: 22
                 >
               >
             >
@@ -1471,8 +1711,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 120
+                  col: 19
+                >
+                end: <
+                  line: 120
+                  col: 22
                 >
               >
             >
@@ -1482,8 +1728,14 @@ apps: <
             value: <
               primitive: INT
               source_context: <
+                file: "tests/petshop.sysl"
                 start: <
                   line: 116
+                  col: 17
+                >
+                end: <
+                  line: 116
+                  col: 17
                 >
               >
             >
diff --git a/pkg/parse/tests/project.sysl.golden.textpb b/pkg/parse/tests/project.sysl.golden.textpb
index 3ea98994..f08bd6a6 100644
--- a/pkg/parse/tests/project.sysl.golden.textpb
+++ b/pkg/parse/tests/project.sysl.golden.textpb
@@ -1,761 +1,785 @@
-apps {
+apps: <
   key: "A_B"
-  value {
-    name {
+  value: <
+    name: <
       part: "A_B"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "C_D"
-      value {
+      value: <
         name: "C_D"
-        stmt {
-          call {
-            target {
+        stmt: <
+          call: <
+            target: <
               part: "anz_com"
-            }
+            >
             endpoint: "homepage"
-          }
-        }
-        stmt {
-          call {
-            target {
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "Test - App"
-            }
+            >
             endpoint: "Test - Endpoint"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "DDD"
-      value {
+      value: <
         name: "DDD"
-        stmt {
-          cond {
+        stmt: <
+          cond: <
             test: "some condition is true"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "Test - App -> eventName"
-              }
-            }
-            stmt {
-              call {
-                target {
+              >
+            >
+            stmt: <
+              call: <
+                target: <
                   part: "Test - App"
-                }
+                >
                 endpoint: "Endpoint2"
-              }
-            }
-            stmt {
-              cond {
+              >
+            >
+            stmt: <
+              cond: <
                 test: "result not ok"
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "not ok1"
-                  }
-                }
-              }
-            }
-            stmt {
-              group {
+                  >
+                >
+              >
+            >
+            stmt: <
+              group: <
                 title: "else"
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "ok"
-                  }
-                }
-              }
-            }
-          }
-        }
-        stmt {
-          group {
+                  >
+                >
+              >
+            >
+          >
+        >
+        stmt: <
+          group: <
             title: "else some other condition"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "top level else_statment"
-              }
-            }
-            stmt {
-              cond {
+              >
+            >
+            stmt: <
+              cond: <
                 test: "\"some constraint\""
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "ok"
-                  }
-                }
-              }
-            }
-            stmt {
-              group {
+                  >
+                >
+              >
+            >
+            stmt: <
+              group: <
                 title: "Else"
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "not ok"
-                  }
-                }
-              }
-            }
-          }
-        }
-        stmt {
-          action {
+                  >
+                >
+              >
+            >
+          >
+        >
+        stmt: <
+          action: <
             action: "do some more stuff"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "EEE"
-      value {
+      value: <
         name: "EEE"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Send document to customer"
-      value {
+      value: <
         name: "Send document to customer"
-      }
-    }
-  }
-}
-apps {
+      >
+    >
+  >
+>
+apps: <
   key: "External :: App"
-  value {
-    name {
+  value: <
+    name: <
       part: "External"
       part: "App"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "Endpoint"
-      value {
+      value: <
         name: "Endpoint"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "Request"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
                   line: 52
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 14
+                >
+                end: <
+                  line: 52
+                  col: 14
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "val"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
+                  line: 53
+                  col: 15
+                >
+                end: <
                   line: 53
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    types {
+                  col: 15
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    types: <
       key: "Response"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "val"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
+                  line: 55
+                  col: 15
+                >
+                end: <
                   line: 55
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 15
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "My Todo App"
-  value {
-    name {
+  value: <
+    name: <
       part: "My Todo App"
-    }
-    attrs {
+    >
+    attrs: <
       key: "patterns"
-      value {
-        a {
-          elt {
+      value: <
+        a: <
+          elt: <
             s: "webapp"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Add Note"
-      value {
+      value: <
         name: "Add Note"
-        attrs {
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "somepattern"
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Project :: Integrations"
-  value {
-    name {
+  value: <
+    name: <
       part: "Project"
       part: "Integrations"
-    }
-    attrs {
+    >
+    attrs: <
       key: "title"
-      value {
+      value: <
         s: "%(epname): %(eplongname)"
-      }
-    }
-    endpoints {
+      >
+    >
+    endpoints: <
       key: "PROJECT-E2E"
-      value {
+      value: <
         name: "PROJECT-E2E"
         long_name: "End to End Integrations"
-        attrs {
+        attrs: <
           key: "page"
-          value {
+          value: <
             s: "Solution Design Doc"
-          }
-        }
-        attrs {
+          >
+        >
+        attrs: <
           key: "passthrough"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "anz_com"
-              }
-              elt {
+              >
+              elt: <
                 s: "My Todo App"
-              }
-              elt {
+              >
+              elt: <
                 s: "A_B"
-              }
-            }
-          }
-        }
-        stmt {
-          action {
+              >
+            >
+          >
+        >
+        stmt: <
+          action: <
             action: "SomeApp"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "Test - App"
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Project :: Sequences"
-  value {
-    name {
+  value: <
+    name: <
       part: "Project"
       part: "Sequences"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "SEQ-One"
-      value {
+      value: <
         name: "SEQ-One"
-        stmt {
-          call {
-            target {
+        stmt: <
+          call: <
+            target: <
               part: "SomeApp"
-            }
+            >
             endpoint: "FooEndpoint"
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Rest Service"
-  value {
-    name {
+  value: <
+    name: <
       part: "Rest Service"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: ".. * <- *"
-      value {
+      value: <
         name: ".. * <- *"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "GET /foo"
-          }
-          attrs {
+          >
+          attrs: <
             key: "some_id"
-            value {
+            value: <
               s: "project_id"
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "GET /foo"
-      value {
+      value: <
         name: "GET /foo"
-        attrs {
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "rest"
-              }
-            }
-          }
-        }
-        attrs {
+              >
+            >
+          >
+        >
+        attrs: <
           key: "some_id"
-          value {
+          value: <
             s: "project_id"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-        rest_params {
+          >
+        >
+        rest_params: <
           method: GET
           path: "/foo"
-        }
-      }
-    }
-  }
-}
-apps {
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "SomeApp"
-  value {
-    name {
+  value: <
+    name: <
       part: "SomeApp"
-    }
-    attrs {
+    >
+    attrs: <
       key: "app_desc"
-      value {
-        s: "this comment belongs to the app defined \'above\'"
-      }
-    }
-    attrs {
+      value: <
+        s: "this comment belongs to the app defined 'above'"
+      >
+    >
+    attrs: <
       key: "array"
-      value {
-        a {
-          elt {
+      value: <
+        a: <
+          elt: <
             s: "one"
-          }
-          elt {
+          >
+          elt: <
             s: "two"
-          }
-        }
-      }
-    }
-    attrs {
+          >
+        >
+      >
+    >
+    attrs: <
       key: "array_of_arrays"
-      value {
-        a {
-          elt {
-            a {
-              elt {
+      value: <
+        a: <
+          elt: <
+            a: <
+              elt: <
                 s: "one"
-              }
-              elt {
+              >
+              elt: <
                 s: "two"
-              }
-            }
-          }
-        }
-      }
-    }
-    attrs {
+              >
+            >
+          >
+        >
+      >
+    >
+    attrs: <
       key: "comment"
-      value {
+      value: <
         s: ""
-      }
-    }
-    attrs {
+      >
+    >
+    attrs: <
       key: "comment.second"
-      value {
+      value: <
         s: ""
-      }
-    }
-    attrs {
+      >
+    >
+    attrs: <
       key: "package"
-      value {
+      value: <
         s: ""
-      }
-    }
-    attrs {
+      >
+    >
+    attrs: <
       key: "version"
-      value {
+      value: <
         s: "1.1.1"
-      }
-    }
-    endpoints {
+      >
+    >
+    endpoints: <
       key: ".. * <- *"
-      value {
+      value: <
         name: ".. * <- *"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "FooEndpoint"
-          }
-          attrs {
+          >
+          attrs: <
             key: "some_id"
-            value {
+            value: <
               s: "project_id"
-            }
-          }
-        }
-        stmt {
-          call {
-            target {
+            >
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "Test - App"
-            }
+            >
             endpoint: "Test - Endpoint"
-          }
-          attrs {
+          >
+          attrs: <
             key: "some_id"
-            value {
+            value: <
               s: "project_id"
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Endpoint"
-      value {
+      value: <
         name: "Endpoint"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Event"
-      value {
+      value: <
         name: "Event"
         is_pubsub: true
-        stmt {
-          ret {
-            payload: "\"customer details\""
-          }
-        }
-        param {
+        param: <
           name: "App.member"
-          type {
-            no_type {
-            }
-          }
-        }
-        param {
+          type: <
+            no_type: <
+            >
+          >
+        >
+        param: <
           name: "request"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "SomeApp"
-                }
+                >
                 path: "SomeType"
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+              >
+            >
+          >
+        >
+        stmt: <
+          ret: <
+            payload: "\"customer details\""
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "FooEndpoint"
-      value {
+      value: <
         name: "FooEndpoint"
-        attrs {
+        attrs: <
           key: "some_id"
-          value {
+          value: <
             s: "project_id"
-          }
-        }
-        stmt {
-          call {
-            target {
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "Test - App"
-            }
+            >
             endpoint: "Test - Endpoint"
-          }
-          attrs {
+          >
+          attrs: <
             key: "some_id"
-            value {
+            value: <
               s: "project_id"
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Test - App -> eventName"
-      value {
+      value: <
         name: "Test - App -> eventName"
-        attrs {
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "mq"
-              }
-            }
-          }
-        }
-        source {
+              >
+            >
+          >
+        >
+        source: <
           part: "Test - App"
-        }
-        stmt {
-          action {
+        >
+        stmt: <
+          action: <
             action: "\"\""
-          }
-        }
-        stmt {
-          action {
-            action: "\'\'"
-          }
-        }
-        stmt {
-          action {
-            action: "\'asdf\'"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
+            action: "''"
+          >
+        >
+        stmt: <
+          action: <
+            action: "'asdf'"
+          >
+        >
+        stmt: <
+          action: <
             action: "\"quoted statement: use special chars here like ?? :: etc\""
-          }
-        }
-        stmt {
-          action {
-            action: "\"test: single quotes \'above\'\""
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
+            action: "\"test: single quotes 'above'\""
+          >
+        >
+        stmt: <
+          action: <
             action: "do something"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "| Some multiline comments that you can use for documentation. This is last line."
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "handle event eventName"
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Test - App"
-  value {
-    name {
+  value: <
+    name: <
       part: "Test - App"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "Endpoint2"
-      value {
+      value: <
         name: "Endpoint2"
-        attrs {
+        attrs: <
           key: "ep_desc"
-          value {
+          value: <
             s: "this comment belongs to the Endpoint2 defined above"
-          }
-        }
-        stmt {
-          action {
-            action: "| Single line statement"
-          }
-        }
-        stmt {
-          call {
-            target {
-              part: "Test - App"
-            }
-            endpoint: "eventName"
-          }
-        }
-        param {
+          >
+        >
+        param: <
           name: "request"
-          type {
-            set {
-              type_ref {
-                ref {
-                  appname {
+          type: <
+            set: <
+              type_ref: <
+                ref: <
+                  appname: <
                     part: "SomeApp"
-                  }
+                  >
                   path: "SomeType"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+                >
+              >
+            >
+          >
+        >
+        stmt: <
+          action: <
+            action: "| Single line statement"
+          >
+        >
+        stmt: <
+          call: <
+            target: <
+              part: "Test - App"
+            >
+            endpoint: "eventName"
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Test - Endpoint"
-      value {
+      value: <
         name: "Test - Endpoint"
-        stmt {
-          call {
-            target {
+        param: <
+          name: "request"
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
+                  part: "SomeApp"
+                >
+                path: "SomeType"
+              >
+            >
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "External"
               part: "App"
-            }
+            >
             endpoint: "Endpoint"
-          }
-        }
-        stmt {
-          call {
-            target {
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "Rest Service"
-            }
+            >
             endpoint: "GET /foo"
-          }
-        }
-        stmt {
-          cond {
+          >
+        >
+        stmt: <
+          cond: <
             test: "value == one"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "do something"
-              }
-            }
-          }
-        }
-        stmt {
-          group {
+              >
+            >
+          >
+        >
+        stmt: <
+          group: <
             title: "else if value == two"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "do something else"
-              }
-            }
-          }
-        }
-        stmt {
-          group {
+              >
+            >
+          >
+        >
+        stmt: <
+          group: <
             title: "else"
-            stmt {
-              ret {
+            stmt: <
+              ret: <
                 payload: "ok"
-              }
-            }
-          }
-        }
-        param {
-          name: "request"
-          type {
-            type_ref {
-              ref {
-                appname {
-                  part: "SomeApp"
-                }
-                path: "SomeType"
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+              >
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "another event"
-      value {
+      value: <
         name: "another event"
         is_pubsub: true
-      }
-    }
-    endpoints {
+      >
+    >
+    endpoints: <
       key: "eventName"
-      value {
+      value: <
         name: "eventName"
         is_pubsub: true
-        stmt {
-          call {
-            target {
-              part: "SomeApp"
-            }
-            endpoint: "Test - App -> eventName"
-          }
-        }
-        param {
+        param: <
           name: "in"
-          type {
+          type: <
             primitive: STRING
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+        stmt: <
+          call: <
+            target: <
+              part: "SomeApp"
+            >
+            endpoint: "Test - App -> eventName"
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "anz_com"
-  value {
-    name {
+  value: <
+    name: <
       part: "anz_com"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "homepage"
-      value {
+      value: <
         name: "homepage"
-      }
-    }
-    types {
+      >
+    >
+    types: <
       key: "Response"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "val"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
+                  line: 64
+                  col: 15
+                >
+                end: <
                   line: 64
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
+                  col: 15
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/rest_api_query_params.sysl.golden.textpb b/pkg/parse/tests/rest_api_query_params.sysl.golden.textpb
index 4832dc88..aceb0d7a 100644
--- a/pkg/parse/tests/rest_api_query_params.sysl.golden.textpb
+++ b/pkg/parse/tests/rest_api_query_params.sysl.golden.textpb
@@ -42,8 +42,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/rest_api_query_params.sysl"
                 start: <
                   line: 3
+                  col: 13
+                >
+                end: <
+                  line: 3
+                  col: 19
                 >
               >
             >
@@ -54,8 +60,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/rest_api_query_params.sysl"
                 start: <
                   line: 3
+                  col: 23
+                >
+                end: <
+                  line: 3
+                  col: 32
                 >
               >
             >
@@ -66,8 +78,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/rest_api_query_params.sysl"
                 start: <
                   line: 3
+                  col: 34
+                >
+                end: <
+                  line: 3
+                  col: 44
                 >
               >
             >
@@ -124,8 +142,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/rest_api_query_params.sysl"
                 start: <
                   line: 5
+                  col: 9
+                >
+                end: <
+                  line: 5
+                  col: 23
                 >
               >
             >
@@ -180,8 +204,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/rest_api_query_params.sysl"
                 start: <
                   line: 9
+                  col: 32
+                >
+                end: <
+                  line: 9
+                  col: 38
                 >
               >
             >
@@ -202,8 +232,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/rest_api_query_params.sysl"
                 start: <
                   line: 5
+                  col: 9
+                >
+                end: <
+                  line: 5
+                  col: 23
                 >
               >
             >
diff --git a/pkg/parse/tests/rest_url_params.sysl.golden.textpb b/pkg/parse/tests/rest_url_params.sysl.golden.textpb
index ea691c5f..d90a9775 100644
--- a/pkg/parse/tests/rest_url_params.sysl.golden.textpb
+++ b/pkg/parse/tests/rest_url_params.sysl.golden.textpb
@@ -31,8 +31,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/rest_url_params.sysl"
                 start: <
                   line: 2
+                  col: 5
+                >
+                end: <
+                  line: 2
+                  col: 14
                 >
               >
             >
@@ -42,8 +48,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/rest_url_params.sysl"
                 start: <
                   line: 3
+                  col: 9
+                >
+                end: <
+                  line: 3
+                  col: 18
                 >
               >
             >
@@ -53,8 +65,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/rest_url_params.sysl"
                 start: <
                   line: 4
+                  col: 13
+                >
+                end: <
+                  line: 4
+                  col: 23
                 >
               >
             >
@@ -64,8 +82,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/rest_url_params.sysl"
                 start: <
                   line: 5
+                  col: 17
+                >
+                end: <
+                  line: 5
+                  col: 26
                 >
               >
             >
@@ -75,8 +99,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/rest_url_params.sysl"
                 start: <
                   line: 6
+                  col: 21
+                >
+                end: <
+                  line: 6
+                  col: 31
                 >
               >
             >
diff --git a/pkg/parse/tests/school.sysl.golden.textpb b/pkg/parse/tests/school.sysl.golden.textpb
index ae44f0ed..6caef206 100644
--- a/pkg/parse/tests/school.sysl.golden.textpb
+++ b/pkg/parse/tests/school.sysl.golden.textpb
@@ -1,113 +1,131 @@
-apps {
+apps: <
   key: "School"
-  value {
-    name {
+  value: <
+    name: <
       part: "School"
-    }
-    types {
+    >
+    types: <
       key: "Class"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "Id"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "patterns"
-                value {
-                  a {
-                    elt {
+                value: <
+                  a: <
+                    elt: <
                       s: "pk"
-                    }
-                    elt {
+                    >
+                    elt: <
                       s: "autoinc"
-                    }
-                  }
-                }
-              }
-              source_context {
-                start {
+                    >
+                  >
+                >
+              >
+              source_context: <
+                file: "school.sysl"
+                start: <
                   line: 3
-                }
-              }
-            }
-          }
-          primary_key {
+                  col: 14
+                >
+                end: <
+                  line: 3
+                  col: 32
+                >
+              >
+            >
+          >
+          primary_key: <
             attr_name: "Id"
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "Student"
-      value {
-        relation {
-          attr_defs {
+      value: <
+        relation: <
+          attr_defs: <
             key: "ClassId"
-            value {
-              attrs {
-                key: "description"
-                value {
-                  s: "describe the table"
-                }
-              }
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "School"
-                  }
+                  >
                   path: "Student"
-                }
-                ref {
+                >
+                ref: <
                   path: "Class"
                   path: "Idd"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              attrs: <
+                key: "description"
+                value: <
+                  s: "describe the table"
+                >
+              >
+              source_context: <
+                file: "school.sysl"
+                start: <
+                  line: 7
+                  col: 19
+                >
+                end: <
                   line: 7
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 25
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "Id"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "describe the table"
-                }
-              }
-              attrs {
+                >
+              >
+              attrs: <
                 key: "patterns"
-                value {
-                  a {
-                    elt {
+                value: <
+                  a: <
+                    elt: <
                       s: "pk"
-                    }
-                  }
-                }
-              }
-              source_context {
-                start {
+                    >
+                  >
+                >
+              >
+              source_context: <
+                file: "school.sysl"
+                start: <
+                  line: 6
+                  col: 14
+                >
+                end: <
                   line: 6
-                }
-              }
-            }
-          }
-          primary_key {
+                  col: 22
+                >
+              >
+            >
+          >
+          primary_key: <
             attr_name: "Id"
-          }
-        }
-        attrs {
+          >
+        >
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "describe the table"
-          }
-        }
-      }
-    }
-  }
-}
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/sequence_type.sysl.golden.textpb b/pkg/parse/tests/sequence_type.sysl.golden.textpb
index a9d3942d..d01e7cc6 100644
--- a/pkg/parse/tests/sequence_type.sysl.golden.textpb
+++ b/pkg/parse/tests/sequence_type.sysl.golden.textpb
@@ -14,8 +14,13 @@ apps: <
               sequence: <
                 primitive: INT
                 source_context: <
+                  file: "tests/sequence_type.sysl"
                   start: <
                     line: 4
+                    col: 13
+                  >
+                  end: <
+                    line: 5
                   >
                 >
               >
@@ -27,8 +32,13 @@ apps: <
               >
               opt: true
               source_context: <
+                file: "tests/sequence_type.sysl"
                 start: <
                   line: 4
+                  col: 13
+                >
+                end: <
+                  line: 5
                 >
               >
             >
diff --git a/pkg/parse/tests/test1.sysl.golden.textpb b/pkg/parse/tests/test1.sysl.golden.textpb
index b9828308..7b4f2788 100644
--- a/pkg/parse/tests/test1.sysl.golden.textpb
+++ b/pkg/parse/tests/test1.sysl.golden.textpb
@@ -1,618 +1,642 @@
-apps {
+apps: <
   key: "A_B"
-  value {
-    name {
+  value: <
+    name: <
       part: "A_B"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "C_D"
-      value {
+      value: <
         name: "C_D"
-        stmt {
-          call {
-            target {
+        stmt: <
+          call: <
+            target: <
               part: "anz_com"
-            }
+            >
             endpoint: "homepage"
-          }
-        }
-        stmt {
-          call {
-            target {
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "Test - App"
-            }
+            >
             endpoint: "Test - Endpoint"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "DDD"
-      value {
+      value: <
         name: "DDD"
-        stmt {
-          cond {
+        stmt: <
+          cond: <
             test: "some condition is true"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "Test - App -> eventName"
-              }
-            }
-            stmt {
-              call {
-                target {
+              >
+            >
+            stmt: <
+              call: <
+                target: <
                   part: "Test - App"
-                }
+                >
                 endpoint: "Endpoint2"
-              }
-            }
-            stmt {
-              cond {
+              >
+            >
+            stmt: <
+              cond: <
                 test: "result not ok"
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "not ok1"
-                  }
-                }
-              }
-            }
-            stmt {
-              group {
+                  >
+                >
+              >
+            >
+            stmt: <
+              group: <
                 title: "else"
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "ok"
-                  }
-                }
-              }
-            }
-          }
-        }
-        stmt {
-          group {
+                  >
+                >
+              >
+            >
+          >
+        >
+        stmt: <
+          group: <
             title: "else some other condition"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "top level else_statment"
-              }
-            }
-            stmt {
-              cond {
+              >
+            >
+            stmt: <
+              cond: <
                 test: "\"some constraint\""
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "ok"
-                  }
-                }
-              }
-            }
-            stmt {
-              group {
+                  >
+                >
+              >
+            >
+            stmt: <
+              group: <
                 title: "Else"
-                stmt {
-                  ret {
+                stmt: <
+                  ret: <
                     payload: "not ok"
-                  }
-                }
-              }
-            }
-          }
-        }
-        stmt {
-          action {
+                  >
+                >
+              >
+            >
+          >
+        >
+        stmt: <
+          action: <
             action: "do some more stuff"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "EEE"
-      value {
+      value: <
         name: "EEE"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Send document to customer"
-      value {
+      value: <
         name: "Send document to customer"
-      }
-    }
-  }
-}
-apps {
+      >
+    >
+  >
+>
+apps: <
   key: "External :: App"
-  value {
-    name {
+  value: <
+    name: <
       part: "External"
       part: "App"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "Endpoint"
-      value {
+      value: <
         name: "Endpoint"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "Request"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
                   line: 52
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 14
+                >
+                end: <
+                  line: 52
+                  col: 14
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "val"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
+                  line: 53
+                  col: 15
+                >
+                end: <
                   line: 53
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    types {
+                  col: 15
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    types: <
       key: "Response"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "val"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
+                  line: 55
+                  col: 15
+                >
+                end: <
                   line: 55
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 15
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "My Todo App"
-  value {
-    name {
+  value: <
+    name: <
       part: "My Todo App"
-    }
-    attrs {
+    >
+    attrs: <
       key: "patterns"
-      value {
-        a {
-          elt {
+      value: <
+        a: <
+          elt: <
             s: "webapp"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Add Note"
-      value {
+      value: <
         name: "Add Note"
-        attrs {
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "somepattern"
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Rest Service"
-  value {
-    name {
+  value: <
+    name: <
       part: "Rest Service"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "GET /foo"
-      value {
+      value: <
         name: "GET /foo"
-        attrs {
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "rest"
-              }
-            }
-          }
-        }
-        stmt {
-          action {
+              >
+            >
+          >
+        >
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-        rest_params {
+          >
+        >
+        rest_params: <
           method: GET
           path: "/foo"
-        }
-      }
-    }
-  }
-}
-apps {
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "SomeApp"
-  value {
-    name {
+  value: <
+    name: <
       part: "SomeApp"
-    }
-    attrs {
+    >
+    attrs: <
       key: "app_desc"
-      value {
-        s: "this comment belongs to the app defined \'above\'"
-      }
-    }
-    attrs {
+      value: <
+        s: "this comment belongs to the app defined 'above'"
+      >
+    >
+    attrs: <
       key: "array"
-      value {
-        a {
-          elt {
+      value: <
+        a: <
+          elt: <
             s: "one"
-          }
-          elt {
+          >
+          elt: <
             s: "two"
-          }
-        }
-      }
-    }
-    attrs {
+          >
+        >
+      >
+    >
+    attrs: <
       key: "array_of_arrays"
-      value {
-        a {
-          elt {
-            a {
-              elt {
+      value: <
+        a: <
+          elt: <
+            a: <
+              elt: <
                 s: "one"
-              }
-              elt {
+              >
+              elt: <
                 s: "two"
-              }
-            }
-          }
-        }
-      }
-    }
-    attrs {
+              >
+            >
+          >
+        >
+      >
+    >
+    attrs: <
       key: "comment"
-      value {
+      value: <
         s: ""
-      }
-    }
-    attrs {
+      >
+    >
+    attrs: <
       key: "comment.second"
-      value {
+      value: <
         s: ""
-      }
-    }
-    attrs {
+      >
+    >
+    attrs: <
       key: "package"
-      value {
+      value: <
         s: ""
-      }
-    }
-    attrs {
+      >
+    >
+    attrs: <
       key: "version"
-      value {
+      value: <
         s: "1.1.1"
-      }
-    }
-    endpoints {
+      >
+    >
+    endpoints: <
       key: "Endpoint"
-      value {
+      value: <
         name: "Endpoint"
-        stmt {
-          action {
+        stmt: <
+          action: <
             action: "..."
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Event"
-      value {
+      value: <
         name: "Event"
         is_pubsub: true
-        stmt {
-          ret {
-            payload: "\"customer details\""
-          }
-        }
-        param {
+        param: <
           name: "App.member"
-          type {
-            no_type {
-            }
-          }
-        }
-        param {
+          type: <
+            no_type: <
+            >
+          >
+        >
+        param: <
           name: "request"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "SomeApp"
-                }
+                >
                 path: "SomeType"
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+              >
+            >
+          >
+        >
+        stmt: <
+          ret: <
+            payload: "\"customer details\""
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "FooEndpoint"
-      value {
+      value: <
         name: "FooEndpoint"
-        stmt {
-          call {
-            target {
+        stmt: <
+          call: <
+            target: <
               part: "Test - App"
-            }
+            >
             endpoint: "Test - Endpoint"
-          }
-        }
-      }
-    }
-    endpoints {
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Test - App -> eventName"
-      value {
+      value: <
         name: "Test - App -> eventName"
-        attrs {
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "mq"
-              }
-            }
-          }
-        }
-        source {
+              >
+            >
+          >
+        >
+        source: <
           part: "Test - App"
-        }
-        stmt {
-          action {
+        >
+        stmt: <
+          action: <
             action: "\"\""
-          }
-        }
-        stmt {
-          action {
-            action: "\'\'"
-          }
-        }
-        stmt {
-          action {
-            action: "\'asdf\'"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
+            action: "''"
+          >
+        >
+        stmt: <
+          action: <
+            action: "'asdf'"
+          >
+        >
+        stmt: <
+          action: <
             action: "\"quoted statement: use special chars here like ?? :: etc\""
-          }
-        }
-        stmt {
-          action {
-            action: "\"test: single quotes \'above\'\""
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
+            action: "\"test: single quotes 'above'\""
+          >
+        >
+        stmt: <
+          action: <
             action: "do something"
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "| Some multiline comments that you can use for documentation. This is last line."
-          }
-        }
-        stmt {
-          action {
+          >
+        >
+        stmt: <
+          action: <
             action: "handle event eventName"
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Test - App"
-  value {
-    name {
+  value: <
+    name: <
       part: "Test - App"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "Endpoint2"
-      value {
+      value: <
         name: "Endpoint2"
-        attrs {
+        attrs: <
           key: "ep_desc"
-          value {
+          value: <
             s: "this comment belongs to the Endpoint2 defined above"
-          }
-        }
-        stmt {
-          action {
-            action: "| Single line statement"
-          }
-        }
-        stmt {
-          call {
-            target {
-              part: "Test - App"
-            }
-            endpoint: "eventName"
-          }
-        }
-        param {
+          >
+        >
+        param: <
           name: "request"
-          type {
-            set {
-              type_ref {
-                ref {
-                  appname {
+          type: <
+            set: <
+              type_ref: <
+                ref: <
+                  appname: <
                     part: "SomeApp"
-                  }
+                  >
                   path: "SomeType"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+                >
+              >
+            >
+          >
+        >
+        stmt: <
+          action: <
+            action: "| Single line statement"
+          >
+        >
+        stmt: <
+          call: <
+            target: <
+              part: "Test - App"
+            >
+            endpoint: "eventName"
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "Test - Endpoint"
-      value {
+      value: <
         name: "Test - Endpoint"
-        stmt {
-          call {
-            target {
+        param: <
+          name: "request"
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
+                  part: "SomeApp"
+                >
+                path: "SomeType"
+              >
+            >
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "External"
               part: "App"
-            }
+            >
             endpoint: "Endpoint"
-          }
-        }
-        stmt {
-          call {
-            target {
+          >
+        >
+        stmt: <
+          call: <
+            target: <
               part: "Rest Service"
-            }
+            >
             endpoint: "GET /foo"
-          }
-        }
-        stmt {
-          cond {
+          >
+        >
+        stmt: <
+          cond: <
             test: "value == one"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "do something"
-              }
-            }
-          }
-        }
-        stmt {
-          group {
+              >
+            >
+          >
+        >
+        stmt: <
+          group: <
             title: "else if value == two"
-            stmt {
-              action {
+            stmt: <
+              action: <
                 action: "do something else"
-              }
-            }
-          }
-        }
-        stmt {
-          group {
+              >
+            >
+          >
+        >
+        stmt: <
+          group: <
             title: "else"
-            stmt {
-              ret {
+            stmt: <
+              ret: <
                 payload: "ok"
-              }
-            }
-          }
-        }
-        param {
-          name: "request"
-          type {
-            type_ref {
-              ref {
-                appname {
-                  part: "SomeApp"
-                }
-                path: "SomeType"
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+              >
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "another event"
-      value {
+      value: <
         name: "another event"
         is_pubsub: true
-      }
-    }
-    endpoints {
+      >
+    >
+    endpoints: <
       key: "eventName"
-      value {
+      value: <
         name: "eventName"
         is_pubsub: true
-        stmt {
-          call {
-            target {
-              part: "SomeApp"
-            }
-            endpoint: "Test - App -> eventName"
-          }
-        }
-        param {
+        param: <
           name: "in"
-          type {
+          type: <
             primitive: STRING
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+          >
+        >
+        stmt: <
+          call: <
+            target: <
+              part: "SomeApp"
+            >
+            endpoint: "Test - App -> eventName"
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "anz_com"
-  value {
-    name {
+  value: <
+    name: <
       part: "anz_com"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "homepage"
-      value {
+      value: <
         name: "homepage"
-      }
-    }
-    types {
+      >
+    >
+    types: <
       key: "Response"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "val"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test1.sysl"
+                start: <
+                  line: 64
+                  col: 15
+                >
+                end: <
                   line: 64
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
+                  col: 15
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/test2.sysl.golden.textpb b/pkg/parse/tests/test2.sysl.golden.textpb
index 3cfa73a8..4697bc6f 100644
--- a/pkg/parse/tests/test2.sysl.golden.textpb
+++ b/pkg/parse/tests/test2.sysl.golden.textpb
@@ -1,243 +1,315 @@
-apps {
+apps: <
   key: "Request"
-  value {
-    name {
+  value: <
+    name: <
       part: "Request"
-    }
-    types {
+    >
+    types: <
       key: "Input"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "field1"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
                   line: 22
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 18
+                >
+                end: <
+                  line: 22
+                  col: 18
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Response"
-  value {
-    name {
+  value: <
+    name: <
       part: "Response"
-    }
-    types {
+    >
+    types: <
       key: "Output"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "field1"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "Response"
-                  }
+                  >
                   path: "Output"
-                }
-                ref {
+                >
+                ref: <
                   path: "Request"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
+                  line: 26
+                  col: 18
+                >
+                end: <
                   line: 26
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 18
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Tuple Model"
-  value {
-    name {
+  value: <
+    name: <
       part: "Tuple Model"
-    }
-    types {
+    >
+    types: <
       key: "Foo"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              attrs {
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "some description"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
+                  line: 4
+                  col: 14
+                >
+                end: <
                   line: 4
-                }
-              }
-            }
-          }
-        }
-        attrs {
+                  col: 14
+                >
+              >
+            >
+          >
+        >
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "some description"
-          }
-        }
-      }
-    }
-    types {
+          >
+        >
+      >
+    >
+    types: <
       key: "PersonName"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "first_name"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
                   line: 16
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 22
+                >
+                end: <
+                  line: 16
+                  col: 22
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "last_name"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
+                  line: 18
+                  col: 21
+                >
+                end: <
                   line: 18
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 21
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "middle_name"
-            value {
-              list {
-                type {
+            value: <
+              list: <
+                type: <
                   primitive: STRING
-                  source_context {
-                    start {
+                  source_context: <
+                    file: "tests/test2.sysl"
+                    start: <
                       line: 17
-                    }
-                  }
-                }
-              }
-            }
-          }
-          attr_defs {
+                      col: 29
+                    >
+                    end: <
+                      line: 17
+                      col: 29
+                    >
+                  >
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "title"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
+                  line: 15
+                  col: 17
+                >
+                end: <
                   line: 15
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    types {
+                  col: 17
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    types: <
       key: "TableName"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "fieldname"
-            value {
+            value: <
               primitive: STRING
-              attrs {
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "Multi-line annotation statement"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
+                  line: 10
+                  col: 21
+                >
+                end: <
                   line: 10
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 21
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "fieldname2"
-            value {
-              attrs {
-                key: "description"
-                value {
-                  s: "Multi-line annotation statement"
-                }
-              }
-              set {
+            value: <
+              set: <
                 primitive: STRING
-                source_context {
-                  start {
+                source_context: <
+                  file: "tests/test2.sysl"
+                  start: <
                     line: 11
-                  }
-                }
-              }
-              source_context {
-                start {
-                  line: 11
-                }
-              }
-            }
-          }
-          attr_defs {
-            key: "ids"
-            value {
-              attrs {
+                    col: 22
+                  >
+                  end: <
+                    line: 11
+                    col: 29
+                  >
+                >
+              >
+              attrs: <
                 key: "description"
-                value {
+                value: <
                   s: "Multi-line annotation statement"
-                }
-              }
-              set {
-                type_ref {
-                  context {
-                    appname {
+                >
+              >
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
+                  line: 11
+                  col: 22
+                >
+                end: <
+                  line: 11
+                  col: 29
+                >
+              >
+            >
+          >
+          attr_defs: <
+            key: "ids"
+            value: <
+              set: <
+                type_ref: <
+                  context: <
+                    appname: <
                       part: "Tuple Model"
-                    }
+                    >
                     path: "TableName"
-                  }
-                  ref {
+                  >
+                  ref: <
                     path: "Foo"
-                  }
-                }
-                source_context {
-                  start {
+                  >
+                >
+                source_context: <
+                  file: "tests/test2.sysl"
+                  start: <
+                    line: 12
+                    col: 15
+                  >
+                  end: <
                     line: 12
-                  }
-                }
-              }
-              source_context {
-                start {
+                    col: 22
+                  >
+                >
+              >
+              attrs: <
+                key: "description"
+                value: <
+                  s: "Multi-line annotation statement"
+                >
+              >
+              source_context: <
+                file: "tests/test2.sysl"
+                start: <
+                  line: 12
+                  col: 15
+                >
+                end: <
                   line: 12
-                }
-              }
-            }
-          }
-        }
-        attrs {
+                  col: 22
+                >
+              >
+            >
+          >
+        >
+        attrs: <
           key: "description"
-          value {
+          value: <
             s: "Multi-line annotation statement"
-          }
-        }
-      }
-    }
-  }
-}
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/test4.sysl.golden.textpb b/pkg/parse/tests/test4.sysl.golden.textpb
index c91dd49b..0ff6b1fa 100644
--- a/pkg/parse/tests/test4.sysl.golden.textpb
+++ b/pkg/parse/tests/test4.sysl.golden.textpb
@@ -1,280 +1,334 @@
-apps {
+apps: <
   key: "Browser App"
-  value {
-    name {
+  value: <
+    name: <
       part: "Browser App"
-    }
-    endpoints {
+    >
+    endpoints: <
       key: "EP"
-      value {
+      value: <
         name: "EP"
-        param {
+        param: <
           name: "p1"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "GO"
                   part: "Sample"
                   part: "My Todo App"
-                }
+                >
                 path: "id"
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+              >
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "EP1"
-      value {
+      value: <
         name: "EP1"
-        param {
+        param: <
           name: "p2"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "Sample"
                   part: "My Todo App"
-                }
+                >
                 path: "id"
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+              >
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "EP2"
-      value {
+      value: <
         name: "EP2"
-        param {
+        param: <
           name: "p3"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "My Todo App"
-                }
+                >
                 path: "id"
-              }
-            }
-          }
-        }
-      }
-    }
-    endpoints {
+              >
+            >
+          >
+        >
+      >
+    >
+    endpoints: <
       key: "EP3"
-      value {
+      value: <
         name: "EP3"
-        param {
+        param: <
           name: "p4"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "id"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    types {
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    types: <
       key: "Data"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "id"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "Browser App"
-                  }
+                  >
                   path: "Data"
-                }
-                ref {
-                  appname {
-                    part: "GO "
-                    part: " Sample "
-                  }
+                >
+                ref: <
+                  appname: <
+                    part: "GO"
+                    part: "Sample"
+                  >
                   path: "My Todo App"
                   path: "id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
                   line: 18
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 14
+                >
+                end: <
+                  line: 18
+                  col: 42
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "id2"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "Browser App"
-                  }
+                  >
                   path: "Data"
-                }
-                ref {
-                  appname {
-                    part: "Sample "
-                  }
+                >
+                ref: <
+                  appname: <
+                    part: "Sample"
+                  >
                   path: "My Todo App"
                   path: "id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
+                  line: 19
+                  col: 15
+                >
+                end: <
                   line: 19
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 37
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "id3"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "Browser App"
-                  }
+                  >
                   path: "Data"
-                }
-                ref {
+                >
+                ref: <
                   path: "My Todo App"
                   path: "id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
+                  line: 20
+                  col: 15
+                >
+                end: <
                   line: 20
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 27
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "GO ::Sample:: My Todo App"
-  value {
-    name {
+  value: <
+    name: <
       part: "GO"
       part: "Sample"
       part: "My Todo App"
-    }
-    types {
+    >
+    types: <
       key: "Todo"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
                   line: 3
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 14
+                >
+                end: <
+                  line: 3
+                  col: 14
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "note"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
+                  line: 4
+                  col: 16
+                >
+                end: <
                   line: 4
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 16
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "My Todo App"
-  value {
-    name {
+  value: <
+    name: <
       part: "My Todo App"
-    }
-    types {
+    >
+    types: <
       key: "Todo"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
                   line: 13
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 14
+                >
+                end: <
+                  line: 13
+                  col: 14
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "note"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
+                  line: 14
+                  col: 16
+                >
+                end: <
                   line: 14
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 16
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "Sample::My Todo App"
-  value {
-    name {
+  value: <
+    name: <
       part: "Sample"
       part: "My Todo App"
-    }
-    types {
+    >
+    types: <
       key: "Todo"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
                   line: 8
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 14
+                >
+                end: <
+                  line: 8
+                  col: 14
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "note"
-            value {
+            value: <
               primitive: STRING
-              source_context {
-                start {
+              source_context: <
+                file: "tests/test4.sysl"
+                start: <
+                  line: 9
+                  col: 16
+                >
+                end: <
                   line: 9
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
+                  col: 16
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/test_rest_api.sysl.golden.textpb b/pkg/parse/tests/test_rest_api.sysl.golden.textpb
index e0065500..77268d36 100644
--- a/pkg/parse/tests/test_rest_api.sysl.golden.textpb
+++ b/pkg/parse/tests/test_rest_api.sysl.golden.textpb
@@ -169,8 +169,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 46
+                  col: 15
+                >
+                end: <
+                  line: 46
+                  col: 15
                 >
               >
             >
@@ -352,8 +358,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 35
+                  col: 13
+                >
+                end: <
+                  line: 35
+                  col: 26
                 >
               >
             >
@@ -373,8 +385,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 35
+                  col: 28
+                >
+                end: <
+                  line: 35
+                  col: 43
                 >
               >
             >
@@ -394,8 +412,14 @@ apps: <
                 >
               >
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 35
+                  col: 45
+                >
+                end: <
+                  line: 35
+                  col: 67
                 >
               >
             >
@@ -405,8 +429,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 34
+                  col: 17
+                >
+                end: <
+                  line: 34
+                  col: 25
                 >
               >
             >
@@ -467,8 +497,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 23
+                  col: 17
+                >
+                end: <
+                  line: 23
+                  col: 23
                 >
               >
             >
@@ -479,8 +515,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 23
+                  col: 27
+                >
+                end: <
+                  line: 23
+                  col: 36
                 >
               >
             >
@@ -491,8 +533,14 @@ apps: <
               primitive: INT
               opt: true
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 23
+                  col: 38
+                >
+                end: <
+                  line: 23
+                  col: 48
                 >
               >
             >
@@ -502,8 +550,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 22
+                  col: 9
+                >
+                end: <
+                  line: 22
+                  col: 17
                 >
               >
             >
@@ -696,8 +750,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 22
+                  col: 9
+                >
+                end: <
+                  line: 22
+                  col: 17
                 >
               >
             >
@@ -765,8 +825,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 22
+                  col: 9
+                >
+                end: <
+                  line: 22
+                  col: 17
                 >
               >
             >
@@ -882,8 +948,14 @@ apps: <
             type: <
               primitive: INT
               source_context: <
+                file: "tests/test_rest_api.sysl"
                 start: <
                   line: 22
+                  col: 9
+                >
+                end: <
+                  line: 22
+                  col: 17
                 >
               >
             >
diff --git a/pkg/parse/tests/transform.sysl.golden.textpb b/pkg/parse/tests/transform.sysl.golden.textpb
index 394122be..355ee2fb 100644
--- a/pkg/parse/tests/transform.sysl.golden.textpb
+++ b/pkg/parse/tests/transform.sysl.golden.textpb
@@ -1,769 +1,781 @@
-apps {
+apps: <
   key: "TransformApp"
-  value {
-    name {
+  value: <
+    name: <
       part: "TransformApp"
-    }
-    attrs {
+    >
+    attrs: <
       key: "package"
-      value {
+      value: <
         s: "io.sysl.demo.petshop.views"
-      }
-    }
-    types {
+      >
+    >
+    types: <
       key: "AnonType_0__"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "breed"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "TransformApp"
-                  }
+                  >
                   path: "AnonType_0__"
-                }
-                ref {
-                  appname {
+                >
+                ref: <
+                  appname: <
                     part: "PetShopModel"
-                  }
+                  >
                   path: "Breed"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    types {
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    types: <
       key: "FooType"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "amount"
-            value {
+            value: <
               primitive: DECIMAL
-              constraint {
-                length {
+              constraint: <
+                length: <
                   max: 14
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/transform.sysl"
+                start: <
                   line: 59
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 16
+                >
+                end: <
+                  line: 59
+                  col: 26
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/transform.sysl"
+                start: <
+                  line: 58
+                  col: 12
+                >
+                end: <
                   line: 58
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+                  col: 12
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "NoArgTransform"
-      value {
-        param {
+      value: <
+        param: <
           name: "number1"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        param {
+          >
+        >
+        param: <
           name: "foo"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "Some"
-                }
+                >
                 path: "Type"
-              }
-            }
-          }
-        }
-        ret_type {
-          type_ref {
-            ref {
-              appname {
+              >
+            >
+          >
+        >
+        ret_type: <
+          type_ref: <
+            ref: <
+              appname: <
                 part: "Model"
-              }
+              >
               path: "Type"
-            }
-          }
-        }
-        expr {
-          transform {
-            arg {
+            >
+          >
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "."
-            }
+            >
             scopevar: "scopeVar"
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: SUB
-                    lhs {
-                      binexpr {
+                    lhs: <
+                      binexpr: <
                         op: ADD
-                        lhs {
+                        lhs: <
                           name: "number"
-                        }
-                        rhs {
-                          literal {
+                        >
+                        rhs: <
+                          literal: <
                             i: 1
-                          }
-                        }
-                      }
-                    }
-                    rhs {
+                          >
+                        >
+                      >
+                    >
+                    rhs: <
                       name: "scopeVar"
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-        attrs {
+                    >
+                  >
+                >
+              >
+            >
+          >
+        >
+        attrs: <
           key: "patterns"
-          value {
-            a {
-              elt {
+          value: <
+            a: <
+              elt: <
                 s: "partial"
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "WithArgTransform"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
+          >
+        >
+        ret_type: <
           primitive: INT
-        }
-        expr {
-          transform {
-            arg {
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "scopeVar"
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: SUB
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      literal {
+                    >
+                    rhs: <
+                      literal: <
                         i: 1
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-        attrs {
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+        >
+        attrs: <
           key: "abc"
-          value {
+          value: <
             s: "foo"
-          }
-        }
-      }
-    }
-    views {
+          >
+        >
+      >
+    >
+    views: <
       key: "nestedTransformWithAnonymousType"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
-          type_ref {
-            ref {
-              appname {
+          >
+        >
+        ret_type: <
+          type_ref: <
+            ref: <
+              appname: <
                 part: "Some1"
-              }
+              >
               path: "Type"
-            }
-          }
-        }
-        expr {
-          transform {
-            arg {
+            >
+          >
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              let {
+            stmt: <
+              let: <
                 name: "_breedsAndPets"
-                expr {
-                  transform {
-                    arg {
-                      get_attr {
-                        arg {
+                expr: <
+                  transform: <
+                    arg: <
+                      get_attr: <
+                        arg: <
                           name: "."
-                        }
+                        >
                         attr: "breeds"
-                      }
-                    }
+                      >
+                    >
                     scopevar: "."
-                    stmt {
-                      let {
+                    stmt: <
+                      let: <
                         name: "breedId"
-                        expr {
-                          call {
+                        expr: <
+                          call: <
                             func: "autoinc"
-                          }
-                        }
-                      }
-                    }
-                    stmt {
-                      assign {
+                          >
+                        >
+                      >
+                    >
+                    stmt: <
+                      assign: <
                         name: "breed"
-                        expr {
-                          transform {
-                            arg {
+                        expr: <
+                          transform: <
+                            arg: <
                               name: "."
-                            }
+                            >
                             scopevar: "."
-                            stmt {
-                              assign {
+                            stmt: <
+                              assign: <
                                 name: "breedName"
-                                expr {
-                                  get_attr {
-                                    arg {
+                                expr: <
+                                  get_attr: <
+                                    arg: <
                                       name: "."
-                                    }
+                                    >
                                     attr: "name"
-                                  }
-                                }
-                              }
-                            }
-                          }
-                          type {
-                            type_ref {
-                              context {
-                                appname {
+                                  >
+                                >
+                              >
+                            >
+                          >
+                          type: <
+                            type_ref: <
+                              context: <
+                                appname: <
                                   part: "TransformApp"
-                                }
-                              }
-                              ref {
-                                appname {
+                                >
+                              >
+                              ref: <
+                                appname: <
                                   part: "PetShopModel"
-                                }
+                                >
                                 path: "Breed"
-                              }
-                            }
-                          }
-                        }
-                      }
-                    }
-                  }
-                  type {
-                    set {
-                      type_ref {
-                        context {
-                          appname {
+                              >
+                            >
+                          >
+                        >
+                      >
+                    >
+                  >
+                  type: <
+                    set: <
+                      type_ref: <
+                        context: <
+                          appname: <
                             part: "TransformApp"
-                          }
-                        }
-                        ref {
-                          appname {
+                          >
+                        >
+                        ref: <
+                          appname: <
                             part: "TransformApp"
-                          }
+                          >
                           path: "AnonType_0__"
-                        }
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-          type {
-            type_ref {
-              context {
-                appname {
+                        >
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+          type: <
+            type_ref: <
+              context: <
+                appname: <
                   part: "TransformApp"
-                }
-              }
-              ref {
-                appname {
+                >
+              >
+              ref: <
+                appname: <
                   part: "Some"
-                }
+                >
                 path: "Type"
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "noReturnType"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
-          type_ref {
-            context {
-              appname {
+          >
+        >
+        ret_type: <
+          type_ref: <
+            context: <
+              appname: <
                 part: "TransformApp"
-              }
-            }
-            ref {
-              appname {
+              >
+            >
+            ref: <
+              appname: <
                 part: "Some"
-              }
+              >
               path: "Type"
-            }
-          }
-        }
-        expr {
-          transform {
-            arg {
+            >
+          >
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: ADD
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      literal {
+                    >
+                    rhs: <
+                      literal: <
                         s: "foo"
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-          type {
-            type_ref {
-              context {
-                appname {
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+          type: <
+            type_ref: <
+              context: <
+                appname: <
                   part: "TransformApp"
-                }
-              }
-              ref {
-                appname {
+                >
+              >
+              ref: <
+                appname: <
                   part: "Some"
-                }
+                >
                 path: "Type"
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "noScopeVar"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
+          >
+        >
+        ret_type: <
           primitive: INT
-        }
-        expr {
-          transform {
-            arg {
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: ADD
-                    lhs {
-                      binexpr {
+                    lhs: <
+                      binexpr: <
                         op: MUL
-                        lhs {
+                        lhs: <
                           name: "number"
-                        }
-                        rhs {
-                          literal {
+                        >
+                        rhs: <
+                          literal: <
                             decimal: "1.5"
-                          }
-                        }
-                      }
-                    }
-                    rhs {
-                      literal {
+                          >
+                        >
+                      >
+                    >
+                    rhs: <
+                      literal: <
                         i: 2
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "withAnonymousSetOfReturnType"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
+          >
+        >
+        ret_type: <
           primitive: INT
-        }
-        expr {
-          transform {
-            arg {
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: POW
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      binexpr {
+                    >
+                    rhs: <
+                      binexpr: <
                         op: POW
-                        lhs {
-                          literal {
+                        lhs: <
+                          literal: <
                             i: 2
-                          }
-                        }
-                        rhs {
-                          literal {
+                          >
+                        >
+                        rhs: <
+                          literal: <
                             i: 3
-                          }
-                        }
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+                          >
+                        >
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "withSetOfReturnType"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
-          set {
-            type_ref {
-              ref {
-                appname {
+          >
+        >
+        ret_type: <
+          set: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "Some1"
-                }
+                >
                 path: "Type"
-              }
-            }
-          }
-        }
-        expr {
-          transform {
-            arg {
+              >
+            >
+          >
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: DIV
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
+                    >
+                    rhs: <
                       name: "number"
-                    }
-                  }
-                }
-              }
-            }
-          }
-          type {
-            set {
-              type_ref {
-                context {
-                  appname {
+                    >
+                  >
+                >
+              >
+            >
+          >
+          type: <
+            set: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "TransformApp"
-                  }
-                }
-                ref {
-                  appname {
+                  >
+                >
+                ref: <
+                  appname: <
                     part: "Some"
-                  }
+                  >
                   path: "Type"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "withSomeReturnType"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
+          type: <
             primitive: INT
-          }
-        }
-        ret_type {
-          type_ref {
-            ref {
-              appname {
+          >
+        >
+        ret_type: <
+          type_ref: <
+            ref: <
+              appname: <
                 part: "Some1"
-              }
+              >
               path: "Type"
-            }
-          }
-        }
-        expr {
-          transform {
-            arg {
+            >
+          >
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: ADD
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      literal {
+                    >
+                    rhs: <
+                      literal: <
                         s: "foo"
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-          type {
-            type_ref {
-              context {
-                appname {
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+          type: <
+            type_ref: <
+              context: <
+                appname: <
                   part: "TransformApp"
-                }
-              }
-              ref {
-                appname {
+                >
+              >
+              ref: <
+                appname: <
                   part: "Some"
-                }
+                >
                 path: "Type"
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "withSomeReturnType2"
-      value {
-        param {
+      value: <
+        param: <
           name: "number"
-          type {
-            type_ref {
-              ref {
-                appname {
+          type: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "Sometype"
-                }
-              }
-            }
-          }
-        }
-        ret_type {
-          set {
-            type_ref {
-              ref {
-                appname {
+                >
+              >
+            >
+          >
+        >
+        ret_type: <
+          set: <
+            type_ref: <
+              ref: <
+                appname: <
                   part: "Sometype"
-                }
-              }
-            }
-          }
-        }
-        expr {
-          transform {
-            arg {
+                >
+              >
+            >
+          >
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: ADD
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      literal {
+                    >
+                    rhs: <
+                      literal: <
                         s: "foo"
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-          type {
-            type_ref {
-              context {
-                appname {
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+          type: <
+            type_ref: <
+              context: <
+                appname: <
                   part: "TransformApp"
-                }
-              }
-              ref {
-                appname {
+                >
+              >
+              ref: <
+                appname: <
                   part: "Sometype"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    views {
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+    views: <
       key: "withSomeReturnType3"
-      value {
-        param {
+      value: <
+        param: <
           name: "foo"
-          type {
-            set {
-              type_ref {
-                ref {
-                  appname {
+          type: <
+            set: <
+              type_ref: <
+                ref: <
+                  appname: <
                     part: "Model"
-                  }
+                  >
                   path: "SomeType"
-                }
-              }
-            }
-          }
-        }
-        ret_type {
-          set {
-            type_ref {
-              context {
-                appname {
+                >
+              >
+            >
+          >
+        >
+        ret_type: <
+          set: <
+            type_ref: <
+              context: <
+                appname: <
                   part: "TransformApp"
-                }
-              }
-              ref {
-                appname {
+                >
+              >
+              ref: <
+                appname: <
                   part: "Some"
-                }
+                >
                 path: "Type"
-              }
-            }
-          }
-        }
-        expr {
-          transform {
-            arg {
+              >
+            >
+          >
+        >
+        expr: <
+          transform: <
+            arg: <
               name: "argName"
-            }
+            >
             scopevar: "."
-            stmt {
-              assign {
+            stmt: <
+              assign: <
                 name: "out"
-                expr {
-                  binexpr {
+                expr: <
+                  binexpr: <
                     op: ADD
-                    lhs {
+                    lhs: <
                       name: "number"
-                    }
-                    rhs {
-                      literal {
+                    >
+                    rhs: <
+                      literal: <
                         s: "foo"
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-          type {
-            set {
-              type_ref {
-                context {
-                  appname {
+                      >
+                    >
+                  >
+                >
+              >
+            >
+          >
+          type: <
+            set: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "TransformApp"
-                  }
-                }
-                ref {
-                  appname {
+                  >
+                >
+                ref: <
+                  appname: <
                     part: "Some"
-                  }
+                  >
                   path: "Type"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
diff --git a/pkg/parse/tests/with_spaces.sysl.golden.textpb b/pkg/parse/tests/with_spaces.sysl.golden.textpb
index ad79c521..1a6be9fb 100644
--- a/pkg/parse/tests/with_spaces.sysl.golden.textpb
+++ b/pkg/parse/tests/with_spaces.sysl.golden.textpb
@@ -1,172 +1,208 @@
-apps {
+apps: <
   key: "AnotherApp"
-  value {
-    name {
+  value: <
+    name: <
       part: "AnotherApp"
-    }
-    types {
+    >
+    types: <
       key: "SecondTable"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "Id"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "AnotherApp"
-                  }
+                  >
                   path: "SecondTable"
-                }
-                ref {
-                  appname {
-                    part: "App with "
-                  }
+                >
+                ref: <
+                  appname: <
+                    part: "App with"
+                  >
                   path: "space"
                   path: "Id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/with_spaces.sysl"
+                start: <
                   line: 11
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 14
+                >
+                end: <
+                  line: 11
+                  col: 32
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "Id2"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "AnotherApp"
-                  }
+                  >
                   path: "SecondTable"
-                }
-                ref {
-                  appname {
-                    part: "App with  "
-                  }
+                >
+                ref: <
+                  appname: <
+                    part: "App with"
+                  >
                   path: "space"
                   path: "Id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/with_spaces.sysl"
+                start: <
+                  line: 12
+                  col: 15
+                >
+                end: <
                   line: 12
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 35
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "Id3"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "AnotherApp"
-                  }
+                  >
                   path: "SecondTable"
-                }
-                ref {
-                  appname {
-                    part: "My "
-                    part: " App with  "
-                  }
+                >
+                ref: <
+                  appname: <
+                    part: "My"
+                    part: "App with"
+                  >
                   path: "space"
                   path: "Id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/with_spaces.sysl"
+                start: <
+                  line: 13
+                  col: 15
+                >
+                end: <
                   line: 13
-                }
-              }
-            }
-          }
-          attr_defs {
+                  col: 41
+                >
+              >
+            >
+          >
+          attr_defs: <
             key: "Id4"
-            value {
-              type_ref {
-                context {
-                  appname {
+            value: <
+              type_ref: <
+                context: <
+                  appname: <
                     part: "AnotherApp"
-                  }
+                  >
                   path: "SecondTable"
-                }
-                ref {
-                  appname {
-                    part: "My   "
-                    part: "  App with  "
-                  }
+                >
+                ref: <
+                  appname: <
+                    part: "My"
+                    part: "App with"
+                  >
                   path: "space"
                   path: "Id"
-                }
-              }
-              source_context {
-                start {
+                >
+              >
+              source_context: <
+                file: "tests/with_spaces.sysl"
+                start: <
                   line: 14
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 15
+                >
+                end: <
+                  line: 14
+                  col: 44
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "App with :: space"
-  value {
-    name {
+  value: <
+    name: <
       part: "App with"
       part: "space"
-    }
-    types {
+    >
+    types: <
       key: "SomeTable"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "Id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/with_spaces.sysl"
+                start: <
+                  line: 3
+                  col: 14
+                >
+                end: <
                   line: 3
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-apps {
+                  col: 14
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>
+apps: <
   key: "My ::  App with :: space"
-  value {
-    name {
+  value: <
+    name: <
       part: "My"
       part: "App with"
       part: "space"
-    }
-    types {
+    >
+    types: <
       key: "SomeTable"
-      value {
-        tuple {
-          attr_defs {
+      value: <
+        tuple: <
+          attr_defs: <
             key: "Id"
-            value {
+            value: <
               primitive: INT
-              source_context {
-                start {
+              source_context: <
+                file: "tests/with_spaces.sysl"
+                start: <
+                  line: 7
+                  col: 14
+                >
+                end: <
                   line: 7
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
+                  col: 14
+                >
+              >
+            >
+          >
+        >
+      >
+    >
+  >
+>